From bb4a2851a5a095451743e662a7b7dad9e4b10984 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 20:42:17 +0000 Subject: [PATCH 1/5] specs reader: a float with an exponent is a number; the gallery counts past 255 t27 specs/ml writes its epsilons as 1e-8, 1.0e-5 and -1.0e30. literalValue refused that form, so constsOf threw on adam, attention_mechanism, batchnorm_layer, binary_crossentropy_loss and lamb, and widget-logic could not compare a widget's K_ numbers with them. The decimal pattern now takes an optional exponent; hex and expressions are still refused, and a new test says both. WIDGET_COUNT becomes u16 in the gallery schema: the 27 widgets of course 10 take the gallery from 252 to 279, past what a u8 holds. Refs #1695 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k --- apps/website/scripts/agents-from-specs.mjs | 10 ++++++---- apps/website/scripts/agents-from-specs.test.mjs | 9 +++++++++ apps/website/scripts/widgets-from-spec.mjs | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/website/scripts/agents-from-specs.mjs b/apps/website/scripts/agents-from-specs.mjs index 8fada5eeb1..c231a52608 100644 --- a/apps/website/scripts/agents-from-specs.mjs +++ b/apps/website/scripts/agents-from-specs.mjs @@ -340,10 +340,12 @@ export function literalValue(expr, name = 'literal') { if (expr.value === undefined) throw new Error(`${name}: literal carries no value`) if (raw === 'true') return true if (raw === 'false') return false - // Integers and decimal floats. Hex, binary expressions, struct literals and - // calls appear elsewhere in the corpus and are deliberately still refused: - // this function reads declarations, it does not evaluate them. - if (/^-?\d+(\.\d+)?$/.test(raw)) return Number(raw) + // Integers and decimal floats, with an optional exponent (`1e-8`, `-1.0e30`: the + // epsilons of t27 specs/ml, which the course 10 widgets run). Hex, binary + // expressions, struct literals and calls appear elsewhere in the corpus and are + // deliberately still refused: this function reads declarations, it does not + // evaluate them. + if (/^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(raw)) return Number(raw) throw new Error(`${name}: unsupported literal ${JSON.stringify(raw)}`) } diff --git a/apps/website/scripts/agents-from-specs.test.mjs b/apps/website/scripts/agents-from-specs.test.mjs index 2ba35c271b..3a4b6f3c5e 100644 --- a/apps/website/scripts/agents-from-specs.test.mjs +++ b/apps/website/scripts/agents-from-specs.test.mjs @@ -100,6 +100,15 @@ test('a negative number inside an array is read; a minus over anything else is r assert.throws(() => constsOf(analyze('module m;\npub const N : [1]i32 = [-K];\npub const K : i32 = 1;\n')), /unsupported|minus/) }) +test('a float with an exponent is read as its number; hex is still refused', () => { + // t27 specs/ml writes its epsilons this way (adam.t27 DEFAULT_EPSILON = 1e-8, attention NEG_INF = -1.0e30). + const c = constsOf(analyze('module m;\npub const E : f32 = 1e-8;\npub const F : f32 = 1.0e-5;\npub const G : f32 = -1.0e30;\n')) + assert.equal(c.E.value, 1e-8) + assert.equal(c.F.value, 1e-5) + assert.equal(c.G.value, -1e30) + assert.throws(() => constsOf(analyze('module m;\npub const H : u32 = 0xff;\n')), /unsupported/) +}) + test('signed integers have a shape: in range passes, out of range and the wrong type do not', () => { const c = constsOf(analyze('module m;\npub const T : [3]i32 = [-1, 0, 1];\npub const N : i32 = -5;\npub const B : i8 = -129;\npub const U : u8 = 3;\n')) assert.equal(shapeProblem(c.T, 'arr-i32'), null) diff --git a/apps/website/scripts/widgets-from-spec.mjs b/apps/website/scripts/widgets-from-spec.mjs index 6eebbed17d..7c51919b54 100644 --- a/apps/website/scripts/widgets-from-spec.mjs +++ b/apps/website/scripts/widgets-from-spec.mjs @@ -33,7 +33,7 @@ const REQUIRED = { TAB_PAGE: 'str', POSTS_NOTHING: 'bool', TOOL_BRAND: 'str', TOOL_GALLERY_LINK: 'str', TOOL_SOURCE_LINK: 'str', TOOL_DATA_LABEL: 'str', TOOL_PRIVACY: 'str', TOOL_PRIVACY_FILES: 'str', TOOL_NOSCRIPT: 'str', CATEGORY_COUNT: 'u8', CATEGORY_IDS: 'arr', CATEGORY_NAMES: 'arr', CATEGORY_LINES: 'arr', KINDS: 'arr', - WIDGET_COUNT: 'u8', WIDGET_IDS: 'arr', WIDGET_KINDS: 'arr', WIDGET_CATEGORIES: 'arr', WIDGET_PAGES: 'arr', + WIDGET_COUNT: 'u16', WIDGET_IDS: 'arr', WIDGET_KINDS: 'arr', WIDGET_CATEGORIES: 'arr', WIDGET_PAGES: 'arr', WIDGET_TITLES: 'arr', WIDGET_LINES: 'arr', WIDGET_HOOKS: 'arr', IDEA_COUNT: 'u8', IDEA_IDS: 'arr', IDEA_TITLES: 'arr', IDEA_LINES: 'arr', IDEA_SOURCES: 'arr', } From 7f925b671f2b311390411c99a168d26543b4a83d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 20:42:31 +0000 Subject: [PATCH 2/5] widgets: 27 neural-network widgets, logic compiled from gHashTag/t27 specs/ml Twenty-seven tool widgets, three per module of the neural-networks course: activations (ReLU, sigmoid, tanh, GELU, Swish, ELU), softmax, embeddings and dropout, pooling and batch norm, MSE, cross-entropy and Huber, SGD, RMSProp and Adam, backpropagation, XOR and LAMB, a recurrent cell, LSTM gates and attention, positional encoding, an encoder block and PPO. Each widget opens with the question its lesson asks and computes nothing itself: its logic.js is the fn bodies of one specs/ml spec of t27 master 239b4b059, compiled to wasm by 999 scripts/t27-logic.mjs (usize lowered since 999#4017) and imported with widget-logic.mjs --import. Words are SAY_ and numbers K_ constants of specs/widgets/.t27; the widget specs hold integers only, so a K_ name ending in _C is in hundredths. nn-kit.js builds on dsp-kit.js (controls, presets, URL hash, tiles, plot axes) and adds curves you drag along, bar charts, heat-maps, diverging and heat colour scales and a node-link diagram. nn-conv is average pooling over 2 x 2 windows (pool4_at): the sliding conv2d spec, t27#10612, is not merged, and the widget says so. nn-xor trains the spec's 2-8-1 network in the page and shows the four inputs the spec exposes, not a decision region. The gallery grows from 252 to 279 widgets; the new shelf sits before the wars pin (index 244 to 270) and the pins after it move by 27. The 27 lesson specs are vendored under public/t27/files/specs/ml byte for byte as t27 master; 24 of them replace older copies, read by no course or widget before. Refs #1695 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k --- .../specs/ml/activation/elu_activation.t27 | 97 ++-- .../specs/ml/activation/gelu_activation.t27 | 200 ++++---- .../specs/ml/activation/relu_activation.t27 | 86 ++-- .../ml/activation/sigmoid_activation.t27 | 21 +- .../ml/activation/silu_swish_activation.t27 | 83 ++-- .../t27/files/specs/ml/activation/softmax.t27 | 149 ++++-- .../specs/ml/activation/tanh_activation.t27 | 69 ++- .../files/specs/ml/layers/avgpool2d_layer.t27 | 207 +++++--- .../files/specs/ml/layers/batchnorm_layer.t27 | 197 ++++++-- .../t27/files/specs/ml/layers/dense_layer.t27 | 181 +++++-- .../files/specs/ml/layers/dropout_layer.t27 | 68 ++- .../files/specs/ml/layers/embedding_layer.t27 | 143 ++++-- .../files/specs/ml/layers/maxpool2d_layer.t27 | 165 ++++--- .../ml/loss/binary_crossentropy_loss.t27 | 304 +++++------- .../t27/files/specs/ml/optimizer/adam.t27 | 147 ++++-- .../t27/files/specs/ml/optimizer/lamb.t27 | 319 ++++++------ .../t27/files/specs/ml/optimizer/sgd.t27 | 146 ++++-- .../public/t27/files/specs/ml/pathway/mlp.t27 | 327 +++++++++---- .../ml/recurrent/attention_mechanism.t27 | 410 +++++++++------- .../files/specs/ml/recurrent/lstm_single.t27 | 407 +++++++++------ .../t27/files/specs/ml/recurrent/rnn_cell.t27 | 185 ++++--- .../t27/files/specs/ml/rl/ppo_clip_loss.t27 | 169 +++---- .../specs/ml/transformer/encoder_block.t27 | 374 +++++++++++--- .../ml/transformer/positional_encoding.t27 | 67 ++- apps/website/public/widgets/gallery.t27 | 41 +- apps/website/public/widgets/nn-adam/card.png | Bin 0 -> 50792 bytes .../website/public/widgets/nn-adam/index.html | 47 ++ apps/website/public/widgets/nn-adam/logic.js | 44 ++ apps/website/public/widgets/nn-adam/logic.t27 | 157 ++++++ .../public/widgets/nn-adam/nn-adam.t27 | 87 ++++ apps/website/public/widgets/nn-adam/tool.js | 44 ++ .../public/widgets/nn-attention/card.png | Bin 0 -> 51279 bytes .../public/widgets/nn-attention/index.html | 47 ++ .../public/widgets/nn-attention/logic.js | 40 ++ .../public/widgets/nn-attention/logic.t27 | 307 ++++++++++++ .../widgets/nn-attention/nn-attention.t27 | 75 +++ .../public/widgets/nn-attention/tool.js | 37 ++ .../public/widgets/nn-backprop/card.png | Bin 0 -> 56839 bytes .../public/widgets/nn-backprop/index.html | 47 ++ .../public/widgets/nn-backprop/logic.js | 40 ++ .../public/widgets/nn-backprop/logic.t27 | 214 ++++++++ .../widgets/nn-backprop/nn-backprop.t27 | 75 +++ .../public/widgets/nn-backprop/tool.js | 39 ++ .../public/widgets/nn-batchnorm/card.png | Bin 0 -> 48539 bytes .../public/widgets/nn-batchnorm/index.html | 47 ++ .../public/widgets/nn-batchnorm/logic.js | 36 ++ .../public/widgets/nn-batchnorm/logic.t27 | 205 ++++++++ .../widgets/nn-batchnorm/nn-batchnorm.t27 | 82 ++++ .../public/widgets/nn-batchnorm/tool.js | 40 ++ apps/website/public/widgets/nn-bce/card.png | Bin 0 -> 50312 bytes apps/website/public/widgets/nn-bce/index.html | 47 ++ apps/website/public/widgets/nn-bce/logic.js | 44 ++ apps/website/public/widgets/nn-bce/logic.t27 | 214 ++++++++ apps/website/public/widgets/nn-bce/nn-bce.t27 | 82 ++++ apps/website/public/widgets/nn-bce/tool.js | 37 ++ apps/website/public/widgets/nn-conv/card.png | Bin 0 -> 46014 bytes .../website/public/widgets/nn-conv/index.html | 47 ++ apps/website/public/widgets/nn-conv/logic.js | 44 ++ apps/website/public/widgets/nn-conv/logic.t27 | 222 +++++++++ .../public/widgets/nn-conv/nn-conv.t27 | 79 +++ apps/website/public/widgets/nn-conv/tool.js | 37 ++ .../public/widgets/nn-dropout/card.png | Bin 0 -> 42927 bytes .../public/widgets/nn-dropout/index.html | 47 ++ .../public/widgets/nn-dropout/logic.js | 28 ++ .../public/widgets/nn-dropout/logic.t27 | 133 +++++ .../public/widgets/nn-dropout/nn-dropout.t27 | 77 +++ .../website/public/widgets/nn-dropout/tool.js | 33 ++ apps/website/public/widgets/nn-elu/card.png | Bin 0 -> 47349 bytes apps/website/public/widgets/nn-elu/index.html | 47 ++ apps/website/public/widgets/nn-elu/logic.js | 40 ++ apps/website/public/widgets/nn-elu/logic.t27 | 122 +++++ apps/website/public/widgets/nn-elu/nn-elu.t27 | 82 ++++ apps/website/public/widgets/nn-elu/tool.js | 38 ++ .../public/widgets/nn-embedding/card.png | Bin 0 -> 39510 bytes .../public/widgets/nn-embedding/index.html | 47 ++ .../public/widgets/nn-embedding/logic.js | 36 ++ .../public/widgets/nn-embedding/logic.t27 | 165 +++++++ .../widgets/nn-embedding/nn-embedding.t27 | 77 +++ .../public/widgets/nn-embedding/tool.js | 37 ++ .../public/widgets/nn-encoder/card.png | Bin 0 -> 44025 bytes .../public/widgets/nn-encoder/index.html | 47 ++ .../public/widgets/nn-encoder/logic.js | 40 ++ .../public/widgets/nn-encoder/logic.t27 | 371 ++++++++++++++ .../public/widgets/nn-encoder/nn-encoder.t27 | 75 +++ .../website/public/widgets/nn-encoder/tool.js | 34 ++ apps/website/public/widgets/nn-gelu/card.png | Bin 0 -> 51583 bytes .../website/public/widgets/nn-gelu/index.html | 47 ++ apps/website/public/widgets/nn-gelu/logic.js | 39 ++ apps/website/public/widgets/nn-gelu/logic.t27 | 167 +++++++ .../public/widgets/nn-gelu/nn-gelu.t27 | 75 +++ apps/website/public/widgets/nn-gelu/tool.js | 35 ++ apps/website/public/widgets/nn-huber/card.png | Bin 0 -> 55999 bytes .../public/widgets/nn-huber/index.html | 47 ++ apps/website/public/widgets/nn-huber/logic.js | 27 + .../website/public/widgets/nn-huber/logic.t27 | 94 ++++ .../public/widgets/nn-huber/nn-huber.t27 | 78 +++ apps/website/public/widgets/nn-huber/tool.js | 40 ++ apps/website/public/widgets/nn-kit.css | 22 + apps/website/public/widgets/nn-kit.js | 193 ++++++++ apps/website/public/widgets/nn-lamb/card.png | Bin 0 -> 45118 bytes .../website/public/widgets/nn-lamb/index.html | 47 ++ apps/website/public/widgets/nn-lamb/logic.js | 48 ++ apps/website/public/widgets/nn-lamb/logic.t27 | 246 ++++++++++ .../public/widgets/nn-lamb/nn-lamb.t27 | 73 +++ apps/website/public/widgets/nn-lamb/tool.js | 34 ++ apps/website/public/widgets/nn-lstm/card.png | Bin 0 -> 65435 bytes .../website/public/widgets/nn-lstm/index.html | 47 ++ apps/website/public/widgets/nn-lstm/logic.js | 48 ++ apps/website/public/widgets/nn-lstm/logic.t27 | 325 ++++++++++++ .../public/widgets/nn-lstm/nn-lstm.t27 | 87 ++++ apps/website/public/widgets/nn-lstm/tool.js | 35 ++ .../public/widgets/nn-maxpool/card.png | Bin 0 -> 43202 bytes .../public/widgets/nn-maxpool/index.html | 47 ++ .../public/widgets/nn-maxpool/logic.js | 28 ++ .../public/widgets/nn-maxpool/logic.t27 | 147 ++++++ .../public/widgets/nn-maxpool/nn-maxpool.t27 | 84 ++++ .../website/public/widgets/nn-maxpool/tool.js | 44 ++ apps/website/public/widgets/nn-mse/card.png | Bin 0 -> 43230 bytes apps/website/public/widgets/nn-mse/index.html | 47 ++ apps/website/public/widgets/nn-mse/logic.js | 32 ++ apps/website/public/widgets/nn-mse/logic.t27 | 98 ++++ apps/website/public/widgets/nn-mse/nn-mse.t27 | 79 +++ apps/website/public/widgets/nn-mse/tool.js | 46 ++ .../public/widgets/nn-positions/card.png | Bin 0 -> 80432 bytes .../public/widgets/nn-positions/index.html | 47 ++ .../public/widgets/nn-positions/logic.js | 28 ++ .../public/widgets/nn-positions/logic.t27 | 88 ++++ .../widgets/nn-positions/nn-positions.t27 | 71 +++ .../public/widgets/nn-positions/tool.js | 42 ++ apps/website/public/widgets/nn-ppo/card.png | Bin 0 -> 41598 bytes apps/website/public/widgets/nn-ppo/index.html | 47 ++ apps/website/public/widgets/nn-ppo/logic.js | 43 ++ apps/website/public/widgets/nn-ppo/logic.t27 | 197 ++++++++ apps/website/public/widgets/nn-ppo/nn-ppo.t27 | 84 ++++ apps/website/public/widgets/nn-ppo/tool.js | 40 ++ apps/website/public/widgets/nn-relu/card.png | Bin 0 -> 46904 bytes .../website/public/widgets/nn-relu/index.html | 47 ++ apps/website/public/widgets/nn-relu/logic.js | 32 ++ apps/website/public/widgets/nn-relu/logic.t27 | 135 +++++ .../public/widgets/nn-relu/nn-relu.t27 | 82 ++++ apps/website/public/widgets/nn-relu/tool.js | 38 ++ .../public/widgets/nn-rmsprop/card.png | Bin 0 -> 54199 bytes .../public/widgets/nn-rmsprop/index.html | 47 ++ .../public/widgets/nn-rmsprop/logic.js | 28 ++ .../public/widgets/nn-rmsprop/logic.t27 | 99 ++++ .../public/widgets/nn-rmsprop/nn-rmsprop.t27 | 81 +++ .../website/public/widgets/nn-rmsprop/tool.js | 37 ++ apps/website/public/widgets/nn-rnn/card.png | Bin 0 -> 38490 bytes apps/website/public/widgets/nn-rnn/index.html | 47 ++ apps/website/public/widgets/nn-rnn/logic.js | 40 ++ apps/website/public/widgets/nn-rnn/logic.t27 | 190 +++++++ apps/website/public/widgets/nn-rnn/nn-rnn.t27 | 74 +++ apps/website/public/widgets/nn-rnn/tool.js | 44 ++ apps/website/public/widgets/nn-sgd/card.png | Bin 0 -> 51813 bytes apps/website/public/widgets/nn-sgd/index.html | 47 ++ apps/website/public/widgets/nn-sgd/logic.js | 40 ++ apps/website/public/widgets/nn-sgd/logic.t27 | 164 +++++++ apps/website/public/widgets/nn-sgd/nn-sgd.t27 | 85 ++++ apps/website/public/widgets/nn-sgd/tool.js | 42 ++ .../public/widgets/nn-sigmoid/card.png | Bin 0 -> 43774 bytes .../public/widgets/nn-sigmoid/index.html | 47 ++ .../public/widgets/nn-sigmoid/logic.js | 27 + .../public/widgets/nn-sigmoid/logic.t27 | 96 ++++ .../public/widgets/nn-sigmoid/nn-sigmoid.t27 | 75 +++ .../website/public/widgets/nn-sigmoid/tool.js | 36 ++ apps/website/public/widgets/nn-silu/card.png | Bin 0 -> 49261 bytes .../website/public/widgets/nn-silu/index.html | 47 ++ apps/website/public/widgets/nn-silu/logic.js | 40 ++ apps/website/public/widgets/nn-silu/logic.t27 | 135 +++++ .../public/widgets/nn-silu/nn-silu.t27 | 83 ++++ apps/website/public/widgets/nn-silu/tool.js | 37 ++ .../public/widgets/nn-softmax/card.png | Bin 0 -> 44030 bytes .../public/widgets/nn-softmax/index.html | 47 ++ .../public/widgets/nn-softmax/logic.js | 40 ++ .../public/widgets/nn-softmax/logic.t27 | 166 +++++++ .../public/widgets/nn-softmax/nn-softmax.t27 | 80 +++ .../website/public/widgets/nn-softmax/tool.js | 41 ++ apps/website/public/widgets/nn-tanh/card.png | Bin 0 -> 46081 bytes .../website/public/widgets/nn-tanh/index.html | 47 ++ apps/website/public/widgets/nn-tanh/logic.js | 36 ++ apps/website/public/widgets/nn-tanh/logic.t27 | 96 ++++ .../public/widgets/nn-tanh/nn-tanh.t27 | 77 +++ apps/website/public/widgets/nn-tanh/tool.js | 40 ++ apps/website/public/widgets/nn-xor/card.png | Bin 0 -> 46495 bytes apps/website/public/widgets/nn-xor/index.html | 47 ++ apps/website/public/widgets/nn-xor/logic.js | 32 ++ apps/website/public/widgets/nn-xor/logic.t27 | 324 ++++++++++++ apps/website/public/widgets/nn-xor/nn-xor.t27 | 81 +++ apps/website/public/widgets/nn-xor/tool.js | 46 ++ apps/website/specs/widgets/gallery.t27 | 41 +- apps/website/specs/widgets/nn-adam.t27 | 87 ++++ apps/website/specs/widgets/nn-attention.t27 | 75 +++ apps/website/specs/widgets/nn-backprop.t27 | 75 +++ apps/website/specs/widgets/nn-batchnorm.t27 | 82 ++++ apps/website/specs/widgets/nn-bce.t27 | 82 ++++ apps/website/specs/widgets/nn-conv.t27 | 79 +++ apps/website/specs/widgets/nn-dropout.t27 | 77 +++ apps/website/specs/widgets/nn-elu.t27 | 82 ++++ apps/website/specs/widgets/nn-embedding.t27 | 77 +++ apps/website/specs/widgets/nn-encoder.t27 | 75 +++ apps/website/specs/widgets/nn-gelu.t27 | 75 +++ apps/website/specs/widgets/nn-huber.t27 | 78 +++ apps/website/specs/widgets/nn-lamb.t27 | 73 +++ apps/website/specs/widgets/nn-lstm.t27 | 87 ++++ apps/website/specs/widgets/nn-maxpool.t27 | 84 ++++ apps/website/specs/widgets/nn-mse.t27 | 79 +++ apps/website/specs/widgets/nn-positions.t27 | 71 +++ apps/website/specs/widgets/nn-ppo.t27 | 84 ++++ apps/website/specs/widgets/nn-relu.t27 | 82 ++++ apps/website/specs/widgets/nn-rmsprop.t27 | 81 +++ apps/website/specs/widgets/nn-rnn.t27 | 74 +++ apps/website/specs/widgets/nn-sgd.t27 | 85 ++++ apps/website/specs/widgets/nn-sigmoid.t27 | 75 +++ apps/website/specs/widgets/nn-silu.t27 | 83 ++++ apps/website/specs/widgets/nn-softmax.t27 | 80 +++ apps/website/specs/widgets/nn-tanh.t27 | 77 +++ apps/website/specs/widgets/nn-xor.t27 | 81 +++ .../website/src/lib/queenWidgets.generated.ts | 463 +++++++++++++++++- 218 files changed, 16121 insertions(+), 1639 deletions(-) create mode 100644 apps/website/public/widgets/nn-adam/card.png create mode 100644 apps/website/public/widgets/nn-adam/index.html create mode 100644 apps/website/public/widgets/nn-adam/logic.js create mode 100644 apps/website/public/widgets/nn-adam/logic.t27 create mode 100644 apps/website/public/widgets/nn-adam/nn-adam.t27 create mode 100644 apps/website/public/widgets/nn-adam/tool.js create mode 100644 apps/website/public/widgets/nn-attention/card.png create mode 100644 apps/website/public/widgets/nn-attention/index.html create mode 100644 apps/website/public/widgets/nn-attention/logic.js create mode 100644 apps/website/public/widgets/nn-attention/logic.t27 create mode 100644 apps/website/public/widgets/nn-attention/nn-attention.t27 create mode 100644 apps/website/public/widgets/nn-attention/tool.js create mode 100644 apps/website/public/widgets/nn-backprop/card.png create mode 100644 apps/website/public/widgets/nn-backprop/index.html create mode 100644 apps/website/public/widgets/nn-backprop/logic.js create mode 100644 apps/website/public/widgets/nn-backprop/logic.t27 create mode 100644 apps/website/public/widgets/nn-backprop/nn-backprop.t27 create mode 100644 apps/website/public/widgets/nn-backprop/tool.js create mode 100644 apps/website/public/widgets/nn-batchnorm/card.png create mode 100644 apps/website/public/widgets/nn-batchnorm/index.html create mode 100644 apps/website/public/widgets/nn-batchnorm/logic.js create mode 100644 apps/website/public/widgets/nn-batchnorm/logic.t27 create mode 100644 apps/website/public/widgets/nn-batchnorm/nn-batchnorm.t27 create mode 100644 apps/website/public/widgets/nn-batchnorm/tool.js create mode 100644 apps/website/public/widgets/nn-bce/card.png create mode 100644 apps/website/public/widgets/nn-bce/index.html create mode 100644 apps/website/public/widgets/nn-bce/logic.js create mode 100644 apps/website/public/widgets/nn-bce/logic.t27 create mode 100644 apps/website/public/widgets/nn-bce/nn-bce.t27 create mode 100644 apps/website/public/widgets/nn-bce/tool.js create mode 100644 apps/website/public/widgets/nn-conv/card.png create mode 100644 apps/website/public/widgets/nn-conv/index.html create mode 100644 apps/website/public/widgets/nn-conv/logic.js create mode 100644 apps/website/public/widgets/nn-conv/logic.t27 create mode 100644 apps/website/public/widgets/nn-conv/nn-conv.t27 create mode 100644 apps/website/public/widgets/nn-conv/tool.js create mode 100644 apps/website/public/widgets/nn-dropout/card.png create mode 100644 apps/website/public/widgets/nn-dropout/index.html create mode 100644 apps/website/public/widgets/nn-dropout/logic.js create mode 100644 apps/website/public/widgets/nn-dropout/logic.t27 create mode 100644 apps/website/public/widgets/nn-dropout/nn-dropout.t27 create mode 100644 apps/website/public/widgets/nn-dropout/tool.js create mode 100644 apps/website/public/widgets/nn-elu/card.png create mode 100644 apps/website/public/widgets/nn-elu/index.html create mode 100644 apps/website/public/widgets/nn-elu/logic.js create mode 100644 apps/website/public/widgets/nn-elu/logic.t27 create mode 100644 apps/website/public/widgets/nn-elu/nn-elu.t27 create mode 100644 apps/website/public/widgets/nn-elu/tool.js create mode 100644 apps/website/public/widgets/nn-embedding/card.png create mode 100644 apps/website/public/widgets/nn-embedding/index.html create mode 100644 apps/website/public/widgets/nn-embedding/logic.js create mode 100644 apps/website/public/widgets/nn-embedding/logic.t27 create mode 100644 apps/website/public/widgets/nn-embedding/nn-embedding.t27 create mode 100644 apps/website/public/widgets/nn-embedding/tool.js create mode 100644 apps/website/public/widgets/nn-encoder/card.png create mode 100644 apps/website/public/widgets/nn-encoder/index.html create mode 100644 apps/website/public/widgets/nn-encoder/logic.js create mode 100644 apps/website/public/widgets/nn-encoder/logic.t27 create mode 100644 apps/website/public/widgets/nn-encoder/nn-encoder.t27 create mode 100644 apps/website/public/widgets/nn-encoder/tool.js create mode 100644 apps/website/public/widgets/nn-gelu/card.png create mode 100644 apps/website/public/widgets/nn-gelu/index.html create mode 100644 apps/website/public/widgets/nn-gelu/logic.js create mode 100644 apps/website/public/widgets/nn-gelu/logic.t27 create mode 100644 apps/website/public/widgets/nn-gelu/nn-gelu.t27 create mode 100644 apps/website/public/widgets/nn-gelu/tool.js create mode 100644 apps/website/public/widgets/nn-huber/card.png create mode 100644 apps/website/public/widgets/nn-huber/index.html create mode 100644 apps/website/public/widgets/nn-huber/logic.js create mode 100644 apps/website/public/widgets/nn-huber/logic.t27 create mode 100644 apps/website/public/widgets/nn-huber/nn-huber.t27 create mode 100644 apps/website/public/widgets/nn-huber/tool.js create mode 100644 apps/website/public/widgets/nn-kit.css create mode 100644 apps/website/public/widgets/nn-kit.js create mode 100644 apps/website/public/widgets/nn-lamb/card.png create mode 100644 apps/website/public/widgets/nn-lamb/index.html create mode 100644 apps/website/public/widgets/nn-lamb/logic.js create mode 100644 apps/website/public/widgets/nn-lamb/logic.t27 create mode 100644 apps/website/public/widgets/nn-lamb/nn-lamb.t27 create mode 100644 apps/website/public/widgets/nn-lamb/tool.js create mode 100644 apps/website/public/widgets/nn-lstm/card.png create mode 100644 apps/website/public/widgets/nn-lstm/index.html create mode 100644 apps/website/public/widgets/nn-lstm/logic.js create mode 100644 apps/website/public/widgets/nn-lstm/logic.t27 create mode 100644 apps/website/public/widgets/nn-lstm/nn-lstm.t27 create mode 100644 apps/website/public/widgets/nn-lstm/tool.js create mode 100644 apps/website/public/widgets/nn-maxpool/card.png create mode 100644 apps/website/public/widgets/nn-maxpool/index.html create mode 100644 apps/website/public/widgets/nn-maxpool/logic.js create mode 100644 apps/website/public/widgets/nn-maxpool/logic.t27 create mode 100644 apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 create mode 100644 apps/website/public/widgets/nn-maxpool/tool.js create mode 100644 apps/website/public/widgets/nn-mse/card.png create mode 100644 apps/website/public/widgets/nn-mse/index.html create mode 100644 apps/website/public/widgets/nn-mse/logic.js create mode 100644 apps/website/public/widgets/nn-mse/logic.t27 create mode 100644 apps/website/public/widgets/nn-mse/nn-mse.t27 create mode 100644 apps/website/public/widgets/nn-mse/tool.js create mode 100644 apps/website/public/widgets/nn-positions/card.png create mode 100644 apps/website/public/widgets/nn-positions/index.html create mode 100644 apps/website/public/widgets/nn-positions/logic.js create mode 100644 apps/website/public/widgets/nn-positions/logic.t27 create mode 100644 apps/website/public/widgets/nn-positions/nn-positions.t27 create mode 100644 apps/website/public/widgets/nn-positions/tool.js create mode 100644 apps/website/public/widgets/nn-ppo/card.png create mode 100644 apps/website/public/widgets/nn-ppo/index.html create mode 100644 apps/website/public/widgets/nn-ppo/logic.js create mode 100644 apps/website/public/widgets/nn-ppo/logic.t27 create mode 100644 apps/website/public/widgets/nn-ppo/nn-ppo.t27 create mode 100644 apps/website/public/widgets/nn-ppo/tool.js create mode 100644 apps/website/public/widgets/nn-relu/card.png create mode 100644 apps/website/public/widgets/nn-relu/index.html create mode 100644 apps/website/public/widgets/nn-relu/logic.js create mode 100644 apps/website/public/widgets/nn-relu/logic.t27 create mode 100644 apps/website/public/widgets/nn-relu/nn-relu.t27 create mode 100644 apps/website/public/widgets/nn-relu/tool.js create mode 100644 apps/website/public/widgets/nn-rmsprop/card.png create mode 100644 apps/website/public/widgets/nn-rmsprop/index.html create mode 100644 apps/website/public/widgets/nn-rmsprop/logic.js create mode 100644 apps/website/public/widgets/nn-rmsprop/logic.t27 create mode 100644 apps/website/public/widgets/nn-rmsprop/nn-rmsprop.t27 create mode 100644 apps/website/public/widgets/nn-rmsprop/tool.js create mode 100644 apps/website/public/widgets/nn-rnn/card.png create mode 100644 apps/website/public/widgets/nn-rnn/index.html create mode 100644 apps/website/public/widgets/nn-rnn/logic.js create mode 100644 apps/website/public/widgets/nn-rnn/logic.t27 create mode 100644 apps/website/public/widgets/nn-rnn/nn-rnn.t27 create mode 100644 apps/website/public/widgets/nn-rnn/tool.js create mode 100644 apps/website/public/widgets/nn-sgd/card.png create mode 100644 apps/website/public/widgets/nn-sgd/index.html create mode 100644 apps/website/public/widgets/nn-sgd/logic.js create mode 100644 apps/website/public/widgets/nn-sgd/logic.t27 create mode 100644 apps/website/public/widgets/nn-sgd/nn-sgd.t27 create mode 100644 apps/website/public/widgets/nn-sgd/tool.js create mode 100644 apps/website/public/widgets/nn-sigmoid/card.png create mode 100644 apps/website/public/widgets/nn-sigmoid/index.html create mode 100644 apps/website/public/widgets/nn-sigmoid/logic.js create mode 100644 apps/website/public/widgets/nn-sigmoid/logic.t27 create mode 100644 apps/website/public/widgets/nn-sigmoid/nn-sigmoid.t27 create mode 100644 apps/website/public/widgets/nn-sigmoid/tool.js create mode 100644 apps/website/public/widgets/nn-silu/card.png create mode 100644 apps/website/public/widgets/nn-silu/index.html create mode 100644 apps/website/public/widgets/nn-silu/logic.js create mode 100644 apps/website/public/widgets/nn-silu/logic.t27 create mode 100644 apps/website/public/widgets/nn-silu/nn-silu.t27 create mode 100644 apps/website/public/widgets/nn-silu/tool.js create mode 100644 apps/website/public/widgets/nn-softmax/card.png create mode 100644 apps/website/public/widgets/nn-softmax/index.html create mode 100644 apps/website/public/widgets/nn-softmax/logic.js create mode 100644 apps/website/public/widgets/nn-softmax/logic.t27 create mode 100644 apps/website/public/widgets/nn-softmax/nn-softmax.t27 create mode 100644 apps/website/public/widgets/nn-softmax/tool.js create mode 100644 apps/website/public/widgets/nn-tanh/card.png create mode 100644 apps/website/public/widgets/nn-tanh/index.html create mode 100644 apps/website/public/widgets/nn-tanh/logic.js create mode 100644 apps/website/public/widgets/nn-tanh/logic.t27 create mode 100644 apps/website/public/widgets/nn-tanh/nn-tanh.t27 create mode 100644 apps/website/public/widgets/nn-tanh/tool.js create mode 100644 apps/website/public/widgets/nn-xor/card.png create mode 100644 apps/website/public/widgets/nn-xor/index.html create mode 100644 apps/website/public/widgets/nn-xor/logic.js create mode 100644 apps/website/public/widgets/nn-xor/logic.t27 create mode 100644 apps/website/public/widgets/nn-xor/nn-xor.t27 create mode 100644 apps/website/public/widgets/nn-xor/tool.js create mode 100644 apps/website/specs/widgets/nn-adam.t27 create mode 100644 apps/website/specs/widgets/nn-attention.t27 create mode 100644 apps/website/specs/widgets/nn-backprop.t27 create mode 100644 apps/website/specs/widgets/nn-batchnorm.t27 create mode 100644 apps/website/specs/widgets/nn-bce.t27 create mode 100644 apps/website/specs/widgets/nn-conv.t27 create mode 100644 apps/website/specs/widgets/nn-dropout.t27 create mode 100644 apps/website/specs/widgets/nn-elu.t27 create mode 100644 apps/website/specs/widgets/nn-embedding.t27 create mode 100644 apps/website/specs/widgets/nn-encoder.t27 create mode 100644 apps/website/specs/widgets/nn-gelu.t27 create mode 100644 apps/website/specs/widgets/nn-huber.t27 create mode 100644 apps/website/specs/widgets/nn-lamb.t27 create mode 100644 apps/website/specs/widgets/nn-lstm.t27 create mode 100644 apps/website/specs/widgets/nn-maxpool.t27 create mode 100644 apps/website/specs/widgets/nn-mse.t27 create mode 100644 apps/website/specs/widgets/nn-positions.t27 create mode 100644 apps/website/specs/widgets/nn-ppo.t27 create mode 100644 apps/website/specs/widgets/nn-relu.t27 create mode 100644 apps/website/specs/widgets/nn-rmsprop.t27 create mode 100644 apps/website/specs/widgets/nn-rnn.t27 create mode 100644 apps/website/specs/widgets/nn-sgd.t27 create mode 100644 apps/website/specs/widgets/nn-sigmoid.t27 create mode 100644 apps/website/specs/widgets/nn-silu.t27 create mode 100644 apps/website/specs/widgets/nn-softmax.t27 create mode 100644 apps/website/specs/widgets/nn-tanh.t27 create mode 100644 apps/website/specs/widgets/nn-xor.t27 diff --git a/apps/website/public/t27/files/specs/ml/activation/elu_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/elu_activation.t27 index c0b472c72a..9b2a8b838e 100644 --- a/apps/website/public/t27/files/specs/ml/activation/elu_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/elu_activation.t27 @@ -1,6 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 // t27/specs/ // Derivative | φ² + 1/φ² = 3 | TRINITY +// #8980: `math::exp` named a module this spec never imports, forward_batch grew +// an array with `+`, and every test called a two-argument function with one +// argument and asserted `result != undefined`. Now each test checks a value. module Elu; use base::types; @@ -24,74 +27,96 @@ module Elu; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(x: f32, alpha: f32) → f32 + // forward(x, alpha) = x for x > 0, alpha * (exp(x) - 1) otherwise fn forward(x: f32, alpha: f32) -> f32 { - if x > 0.0 { + if (x > 0.0) { return x; - } else { - return alpha * (math::exp(x) - 1.0); } + return alpha * (exp(x) - 1.0); } - // forward_batch(input: []f32, alpha: f32) → []f32 - fn forward_batch(input: []f32, alpha: f32) -> []f32 { - var result = []f32{}; + // forward_batch: output[i] = forward(input[i], alpha) + fn forward_batch(input: []const f32, alpha: f32, output: []f32) -> void { var i : usize = 0; - while (i < input.len) : (i += 1) { - if (input[i] > 0.0) { - result = result + [input[i]]; - } else { - result = result + [alpha * (math::exp(input[i]) - 1.0)]; - } + while (i < input.len) { + output[i] = forward(input[i], alpha); + i = i + 1; } - return result; } - // derivative(x: f32, alpha: f32) → f32 + // derivative(x, alpha) = 1 for x > 0, alpha * exp(x) otherwise fn derivative(x: f32, alpha: f32) -> f32 { - if x > 0.0 { + if (x > 0.0) { return 1.0; - } else { - return alpha * math::exp(x); } + return alpha * exp(x); + } + + // The inputs the tests and invariants share: one negative, zero, one positive. + fn negative_input() -> f32 { + return -1.0; + } + + fn valid_input() -> f32 { + return 2.0; + } + + fn batch_at(index: usize) -> f32 { + const input : [3]f32 = [-1.0, 0.0, 2.0]; + var output : [3]f32 = [0.0] ** 3; + forward_batch(&input, DEFAULT_ALPHA, &output); + return output[index]; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // ELU(-1) = exp(-1) - 1 = -0.6321206; ELU(2) = 2 test "forward_basic_case" - given input = default_input() - when result = forward(input) - then result != undefined + given input = negative_input() + when result = forward(input, DEFAULT_ALPHA) + then @abs(result - (-0.6321206)) < 0.000001 and forward(valid_input(), DEFAULT_ALPHA) == 2.0 + + // alpha scales only the negative side, and ELU(x) never goes below -alpha (in f32 + // ELU(-20) rounds to exactly -alpha) + test "forward_alpha_scales_negative_side" + given input = negative_input() + when result = forward(input, 0.5) + then @abs(result - 0.5 * forward(input, 1.0)) < 0.000001 and forward(-20.0, 0.5) >= -0.5 test "forward_batch_basic_case" - given input = default_input() - when result = forward_batch(input) - then result != undefined + given input = negative_input() + when result = batch_at(0) + then result == forward(input, DEFAULT_ALPHA) and batch_at(1) == 0.0 and batch_at(2) == 2.0 + // ELU'(-1) = exp(-1) = 0.3678794; ELU'(2) = 1 test "derivative_basic_case" - given input = default_input() - when result = derivative(input) - then result != undefined + given input = negative_input() + when result = derivative(input, DEFAULT_ALPHA) + then @abs(result - 0.3678794) < 0.000001 and derivative(valid_input(), DEFAULT_ALPHA) == 1.0 + + test "derivative_matches_finite_difference" + given slope = (forward(-1.0 + 0.001, DEFAULT_ALPHA) - forward(-1.0 - 0.001, DEFAULT_ALPHA)) / 0.002 + when result = derivative(-1.0, DEFAULT_ALPHA) + then @abs(result - slope) < 0.001 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ invariant elu_constraint_0 - given input = valid_input() - then true // alpha > 0 + assert DEFAULT_ALPHA > 0.0 + // name: elu_formula -- identity on the positive side invariant elu_constraint_1 - given input = valid_input() - then true // name: elu_formula + assert forward(valid_input(), DEFAULT_ALPHA) == valid_input() + // name: derivative -- 1 on the positive side invariant elu_constraint_2 - given input = valid_input() - then true // name: derivative + assert derivative(valid_input(), DEFAULT_ALPHA) == 1.0 + // "Clevert et al. (2016) - Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)": + // ELU is continuous at 0 invariant elu_constraint_3 - given input = valid_input() - then true // "Clevert et al. (2016) - Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)" - + assert forward(0.0, DEFAULT_ALPHA) == 0.0 diff --git a/apps/website/public/t27/files/specs/ml/activation/gelu_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/gelu_activation.t27 index bd7b8c1190..4c2b4a0e53 100644 --- a/apps/website/public/t27/files/specs/ml/activation/gelu_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/gelu_activation.t27 @@ -2,6 +2,11 @@ // t27/specs/ // Based on cumulative distribution function | φ² + 1/φ² = 3 | TRINITY +// #8980: Zig has neither `@tanh` nor `@erf`, so this never compiled. erf is now +// a function of this spec (Abramowitz-Stegun 7.1.26, |error| < 1.5e-7), and the +// exact derivative divides the normal density by sqrt(2 pi), not sqrt(2) (the +// slip was invisible at x = 0, the only point the tests checked). + module Gelu; use base::types; use math::constants; @@ -12,6 +17,8 @@ module Gelu; const SQRT_2_OVER_PI : f32 = 0.7978845608; const SQRT_PI_OVER_2 : f32 = 1.2533141373; + const SQRT_2 : f32 = 1.4142135624; + const SQRT_2_PI : f32 = 2.5066282746; // ═══════════════════════════════════════════════════════════ // 2. Types @@ -25,125 +32,136 @@ module Gelu; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32, output: []f32, config: GELUConfig) → void + // erf(x), Abramowitz-Stegun 7.1.26: max absolute error 1.5e-7 + fn erf(x: f32) -> f32 { + if (x < 0.0) { + return -erf(-x); + } + const t = 1.0 / (1.0 + 0.3275911 * x); + const poly = t * (0.254829592 + t * (-0.284496736 + t * (1.421413741 + t * (-1.453152027 + t * 1.061405429)))); + return 1.0 - poly * exp(-x * x); + } + + // One element. approximate: 0.5 x (1 + tanh(sqrt(2/pi) (x + 0.044715 x^3))); + // exact: 0.5 x (1 + erf(x / sqrt(2))) = x Phi(x) + fn gelu_one(x: f32, approximate: bool) -> f32 { + if (approximate) { + const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x); + return 0.5 * x * (1.0 + tanh(inner)); + } + return 0.5 * x * (1.0 + erf(x / SQRT_2)); + } + + // d/dx of gelu_one + fn gelu_grad_one(x: f32, approximate: bool) -> f32 { + if (approximate) { + const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x); + const tanh_val = tanh(inner); + const sech_sq = 1.0 - tanh_val * tanh_val; + return 0.5 * (1.0 + tanh_val) + 0.5 * x * sech_sq * SQRT_2_OVER_PI * (1.0 + 3.0 * 0.044715 * x * x); + } + // Phi(x) + x phi(x), phi(x) = exp(-x^2 / 2) / sqrt(2 pi) + const cdf = 0.5 * (1.0 + erf(x / SQRT_2)); + const pdf = exp(-0.5 * x * x) / SQRT_2_PI; + return cdf + x * pdf; + } + fn forward(input: []const f32, output: []f32, config: GELUConfig) -> void { - let n = input.len; - for (0..n) |i| { - let x = input[i]; - if (config.approximate) { - // Hendrycks–Gimpel tanh form: 0.5 * x * (1 + tanh(SQRT_2_OVER_PI * (x + 0.044715 * x^3))) - let x_cubed = x * x * x; - let inner = SQRT_2_OVER_PI * (x + 0.044715 * x_cubed); - let tanh_val = @tanh(inner); - output[i] = 0.5 * x * (1.0 + tanh_val); - } else { - // Exact form: 0.5 * x * (1 + erf(x / sqrt(2))) - let sqrt_2 = 1.4142135624; - let erf_arg = x / sqrt_2; - let erf_val = @erf(erf_arg); - output[i] = 0.5 * x * (1.0 + erf_val); - } + var i : usize = 0; + while (i < input.len) { + output[i] = gelu_one(input[i], config.approximate); + i = i + 1; } } - // backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: GELUConfig) → void fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: GELUConfig) -> void { - let n = input.len; - for (0..n) |i| { - let x = input[i]; - let grad_output_val = grad_output[i]; - - if (config.approximate) { - // Derivative of tanh form - let x_cubed = x * x * x; - let inner = SQRT_2_OVER_PI * (x + 0.044715 * x_cubed); - let tanh_val = @tanh(inner); - let sech_sq = 1.0 - tanh_val * tanh_val; - let derivative = 0.5 * (1.0 + tanh_val) + 0.5 * x * sech_sq * SQRT_2_OVER_PI * (1.0 + 3.0 * 0.044715 * x * x); - grad_input[i] = grad_output_val * derivative; - } else { - // Derivative of exact form: Φ(x) + x * φ(x), where φ(x) = exp(-x²/2) / sqrt(2π) - let sqrt_2 = 1.4142135624; - let erf_arg = x / sqrt_2; - let erf_val = @erf(erf_arg); - let phi_x = 0.5 * (1.0 + erf_val); // Φ(x) = normal CDF - let exp_arg = -0.5 * x * x; - let phi_x_derivative = @exp(exp_arg) / sqrt_2; // φ(x) = normal PDF - let derivative = phi_x + x * phi_x_derivative; - grad_input[i] = grad_output_val * derivative; - } + var i : usize = 0; + while (i < input.len) { + grad_input[i] = grad_output[i] * gelu_grad_one(input[i], config.approximate); + i = i + 1; } } + // forward / backward over a one-element slice, for the tests + fn forward_at(x: f32, approximate: bool) -> f32 { + const input : [1]f32 = [x]; + var output : [1]f32 = [0.0]; + forward(&input, &output, GELUConfig{ .approximate = approximate }); + return output[0]; + } + + fn backward_at(x: f32, approximate: bool) -> f32 { + const grad_output : [1]f32 = [1.0]; + const input : [1]f32 = [x]; + var grad_input : [1]f32 = [0.0]; + backward(&grad_output, &input, &grad_input, GELUConfig{ .approximate = approximate }); + return grad_input[0]; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // The product goes through a function so the check runs, not only folds at compile time. + fn product_of(a: f32, b: f32) -> f32 { + return a * b; + } + + fn config_of(approximate: bool) -> GELUConfig { + return GELUConfig{ .approximate = approximate }; + } + test gelu_sqrt_constants_are_reciprocals - given product = SQRT_2_OVER_PI * SQRT_PI_OVER_2 + given product = product_of(SQRT_2_OVER_PI, SQRT_PI_OVER_2) then @abs(product - 1.0) < 0.0000005 test gelu_sqrt_2_over_pi_squares_to_2_over_pi - given squared = SQRT_2_OVER_PI * SQRT_2_OVER_PI + given squared = product_of(SQRT_2_OVER_PI, SQRT_2_OVER_PI) then @abs(squared - 0.63661977) < 0.0000003 test gelu_config_records_the_approximation_choice - given exact = GELUConfig{.approximate=false} - and approx = GELUConfig{.approximate=true} - then !exact.approximate - and approx.approximate + given exact = config_of(false) + when approx = config_of(true) + then !exact.approximate and approx.approximate + + // erf(0) = 0, erf(1) = 0.8427008, erf(-1) = -erf(1) + test gelu_erf_known_values + given at_one = erf(1.0) + when at_zero = erf(0.0) + then @abs(at_zero) < 0.0000002 and @abs(at_one - 0.8427008) < 0.0000003 and erf(-1.0) == -at_one test gelu_forward_zero_input - given input = []f32{0.0} - and output = []f32{0.0} - and exact_config = GELUConfig{.approximate=false} - and approx_config = GELUConfig{.approximate=true} - when forward(input, output, exact_config) - when forward(input, output, approx_config) - then output[0] == 0.0 + given exact = forward_at(0.0, false) + when approx = forward_at(0.0, true) + then exact == 0.0 and approx == 0.0 test gelu_backward_zero_input_derivative - given grad_output = []f32{1.0} - and input = []f32{0.0} - and grad_input = []f32{0.0} - and exact_config = GELUConfig{.approximate=false} - and approx_config = GELUConfig{.approximate=true} - when backward(grad_output, input, grad_input, exact_config) - when backward(grad_output, input, grad_input, approx_config) - then grad_input[0] == 0.5 + given exact = backward_at(0.0, false) + when approx = backward_at(0.0, true) + then @abs(exact - 0.5) < 0.0000002 and approx == 0.5 test gelu_forward_monotonic_positive_tail - given input_small = []f32{1.0} - and input_large = []f32{2.0} - and output_small = []f32{0.0} - and output_large = []f32{0.0} - and config = GELUConfig{.approximate=true} - when forward(input_small, output_small, config) - when forward(input_large, output_large, config) - then output_small[0] < output_large[0] + given small = forward_at(1.0, true) + when large = forward_at(2.0, true) + then small < large + // With the cubic term, approximate GELU(1) = 0.8411920; exact GELU(1) = Phi(1) = 0.8413447. + // Without it, 0.5 (1 + tanh(0.7978846)) = 0.8296438 -- so this pins the term. test gelu_tanh_cubic_coefficient - given input = []f32{1.0} - and output = []f32{0.0} - and config = GELUConfig{.approximate=true} - when forward(input, output, config) - // The cubic coefficient 0.044715 is part of the tanh approximation formula - then true // This test documents the presence of the cubic term + given approx = forward_at(1.0, true) + when exact = forward_at(1.0, false) + then @abs(approx - 0.8411920) < 0.000001 and @abs(exact - 0.8413447) < 0.000001 test gelu_backward_exact_derivative_at_zero - given grad_output = []f32{1.0} - and input = []f32{0.0} - and grad_input = []f32{0.0} - and config = GELUConfig{.approximate=false} - when backward(grad_output, input, grad_input, config) - // At x=0, Φ(0) = 0.5 and φ(0) = 1/sqrt(2π), so derivative = 0.5 + 0 = 0.5 - then grad_input[0] == 0.5 + given result = backward_at(0.0, false) + then @abs(result - 0.5) < 0.0000002 test gelu_forward_approx_derivative_at_zero - given grad_output = []f32{1.0} - and input = []f32{0.0} - and grad_input = []f32{0.0} - and config = GELUConfig{.approximate=true} - when backward(grad_output, input, grad_input, config) - // At x=0, tanh(0) = 0, so derivative = 0.5 * (1 + 0) + 0 = 0.5 - then grad_input[0] == 0.5 \ No newline at end of file + given result = backward_at(0.0, true) + then result == 0.5 + + // The derivative at x = 1 is where the old sqrt(2) slip showed: 1.0833155 exact + test gelu_backward_matches_finite_difference + given exact_slope = (forward_at(1.001, false) - forward_at(0.999, false)) / 0.002 + when approx_slope = (forward_at(1.001, true) - forward_at(0.999, true)) / 0.002 + then @abs(backward_at(1.0, false) - exact_slope) < 0.002 and @abs(backward_at(1.0, true) - approx_slope) < 0.002 and @abs(backward_at(1.0, false) - 1.0833155) < 0.000002 diff --git a/apps/website/public/t27/files/specs/ml/activation/relu_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/relu_activation.t27 index 6f71e91967..b726401b32 100644 --- a/apps/website/public/t27/files/specs/ml/activation/relu_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/relu_activation.t27 @@ -2,6 +2,10 @@ // t27/specs/ // ReLU produces sparse gradients | φ² + 1/φ² = 3 | TRINITY +// #8980: the tests called forward and backward with one or two of their three or +// four arguments, two asserted only `result != undefined`, and the invariants +// asserted `true`. Each test now runs the functions on buffers and checks values. + module Relu; use base::types; use math::constants; @@ -59,53 +63,73 @@ module Relu; // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + fn cfg(slope: f32) -> ReLUConfig { + return ReLUConfig{ .negative_slope = slope, .inplace = false }; + } + + // output[index] of forward over (a, b, c) + fn forward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 { + const input : [3]f32 = [a, b, c]; + var output : [3]f32 = [9.0] ** 3; + forward(&input, &output, cfg(slope)); + return output[index]; + } + + // grad_input[index] of backward over (a, b, c), every grad_output 1 + fn backward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 { + const grad_output : [3]f32 = [1.0, 1.0, 1.0]; + const input : [3]f32 = [a, b, c]; + var grad_input : [3]f32 = [9.0] ** 3; + backward(&grad_output, &input, &grad_input, cfg(slope)); + return grad_input[index]; + } + + // The shared fixture: one negative, zero, one positive. + fn valid_input() -> f32 { + return -2.0; + } + + // max(0, x) on (-2, 0, 2) test "forward_basic_case" - given input = default_input() - when result = forward(input) - then result != undefined + given negative = forward_at(-2.0, 0.0, 2.0, 0.0, 0) + when positive = forward_at(-2.0, 0.0, 2.0, 0.0, 2) + then negative == 0.0 and forward_at(-2.0, 0.0, 2.0, 0.0, 1) == 0.0 and positive == 2.0 test "forward_positive_identity" - given input = [1.0, 2.0, 3.0] - when output = forward(input, ReLUConfig{ .negative_slope = 0.0, .inplace = false }) - then output[0] == 1.0 - and output[1] == 2.0 - and output[2] == 3.0 + given slope = 0.0 + when first = forward_at(1.0, 2.0, 3.0, slope, 0) + then first == 1.0 and forward_at(1.0, 2.0, 3.0, slope, 1) == 2.0 and forward_at(1.0, 2.0, 3.0, slope, 2) == 3.0 test "forward_negative_scaling" - given input = [-1.0, -2.0, -3.0] - when output = forward(input, ReLUConfig{ .negative_slope = 0.5, .inplace = false }) - then output[0] == -0.5 - and output[1] == -1.0 - and output[2] == -1.5 + given slope = 0.5 + when first = forward_at(-1.0, -2.0, -3.0, slope, 0) + then first == -0.5 and forward_at(-1.0, -2.0, -3.0, slope, 1) == -1.0 and forward_at(-1.0, -2.0, -3.0, slope, 2) == -1.5 test "forward_zero_negative_slope" - given input = [-1.0, 0.0, 1.0] - when output = forward(input, ReLUConfig{ .negative_slope = 0.0, .inplace = false }) - then output[0] == 0.0 - and output[1] == 0.0 - and output[2] == 1.0 + given slope = 0.0 + when first = forward_at(-1.0, 0.0, 1.0, slope, 0) + then first == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 1) == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0 + // grad_output * negative_slope for input <= ZERO (0 included), grad_output above it test "backward_input_gate" - given input = [-1.0, 0.0, 1.0] - when grad_input = backward([1.0, 1.0, 1.0], input, ReLUConfig{ .negative_slope = 0.5, .inplace = false }) - then grad_input[0] == 0.5 // grad_output * negative_slope for input <= ZERO - and grad_input[1] == 0.5 // grad_output * negative_slope for input == ZERO - and grad_input[2] == 1.0 // grad_output for input > ZERO + given slope = 0.5 + when first = backward_at(-1.0, 0.0, 1.0, slope, 0) + then first == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 1) == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0 + // Plain ReLU: the gradient is 0 left of zero and passes through right of it test "backward_basic_case" - given input = default_input() - when result = backward(input) - then result != undefined + given negative = backward_at(-2.0, 0.0, 2.0, 0.0, 0) + when positive = backward_at(-2.0, 0.0, 2.0, 0.0, 2) + then negative == 0.0 and positive == 1.0 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // input.len == output.len: forward writes every element of its buffer (none keeps the 9.0 fill) invariant relu_constraint_0 - given input = valid_input() - then true // input.len == output.len + assert forward_at(valid_input(), 0.0, 1.0, 0.0, 0) != 9.0 and forward_at(valid_input(), 0.0, 1.0, 0.0, 2) != 9.0 + // A finite input gives a finite output: ReLU never exceeds its input's magnitude invariant relu_constraint_1 - given input = valid_input() - then true // All inputs must be finite - + assert @abs(forward_at(valid_input(), 0.0, 1.0, 0.5, 0)) <= @abs(valid_input()) diff --git a/apps/website/public/t27/files/specs/ml/activation/sigmoid_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/sigmoid_activation.t27 index 952a430dde..4e6d84ddb3 100644 --- a/apps/website/public/t27/files/specs/ml/activation/sigmoid_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/sigmoid_activation.t27 @@ -53,8 +53,14 @@ module Sigmoid; // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // #8980: through a function, so the check runs and is counted (it folded at compile + // time before, and the report counted it as a vacuous pass). + fn config_size() -> usize { + return @sizeOf(SigmoidConfig); + } + test sigmoid_has_no_tunable_parameter - given size = @sizeOf(SigmoidConfig) + given size = config_size() then size == 0 // sigmoid_config_is_a_placeholder_not_an_empty_struct read std.meta.fields, which t27 @@ -76,4 +82,15 @@ module Sigmoid; test forward_batch_preserves_length given input = []f32{0.0, 1.0, -1.0, 2.0, -2.0} given result = forward_batch(input) - then result.len == input.len \ No newline at end of file + then result.len == input.len + + // sigmoid(-x) = 1 - sigmoid(x); sigmoid(2) = 0.8807971 + test forward_is_symmetric_about_one_half + given up = forward(2.0) + when down = forward(-2.0) + then @abs(up + down - 1.0) < 0.000001 and @abs(up - 0.8807971) < 0.000001 + + // The negative branch never computes exp(+x): no overflow at -100 + test forward_far_left_is_zero_not_nan + given y = forward(-100.0) + then y >= 0.0 and y < 0.000001 diff --git a/apps/website/public/t27/files/specs/ml/activation/silu_swish_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/silu_swish_activation.t27 index b215a4963c..404271397f 100644 --- a/apps/website/public/t27/files/specs/ml/activation/silu_swish_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/silu_swish_activation.t27 @@ -2,6 +2,10 @@ // t27/specs/ // SiLU derivative | φ² + 1/φ² = 3 | TRINITY +// #8980: forward_batch returned its input unchanged, beta was never read, and the +// invariants asserted `true` over an undeclared `valid_input`. SiLU is now +// x * sigmoid(beta * x) (Swish; beta = 1 is SiLU) on scalars and in place on slices. + module SiluSwish; use base::types; use math::constants; @@ -24,30 +28,40 @@ module SiluSwish; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(x: f32, beta: f32) → f32 + // sigmoid(z) = 1 / (1 + exp(-z)) + fn sigmoid(z: f32) -> f32 { + return 1.0 / (1.0 + exp(-z)); + } + + // Swish(x) = x * sigmoid(beta * x); beta = 1 is SiLU fn forward(x: f32, beta: f32) -> f32 { - // SiLU: x * sigmoid(x) = x / (1 + exp(-x)) - // Implementation: compute and store result if needed - let sigmoid_x = 1.0 / (1.0 + exp(-x)); - let result = x * sigmoid_x; - return result; + return x * sigmoid(beta * x); } - // forward_batch(input: []f32, beta: f32) → []f32 + // forward on each element IN PLACE; returns the same slice fn forward_batch(input: []f32, beta: f32) -> []f32 { - // SiLU batch: apply SiLU to each element in the array - // Simple implementation: mark as implemented by processing input - let _ = input.len; // Use input to avoid "not yet implemented" - return input; // Placeholder implementation + var i : usize = 0; + while (i < input.len) { + input[i] = forward(input[i], beta); + i = i + 1; + } + return input; } - // derivative(x: f32, beta: f32) → f32 + // d/dx x sigmoid(beta x) = s + beta x s (1 - s), s = sigmoid(beta x) fn derivative(x: f32, beta: f32) -> f32 { - // SiLU derivative: sigmoid(x) + x * sigmoid(x) * (1 - sigmoid(x)) - // Implementation: compute and store result if needed - let sigmoid_x = 1.0 / (1.0 + exp(-x)); - let result = sigmoid_x + x * sigmoid_x * (1.0 - sigmoid_x); - return result; + const s = sigmoid(beta * x); + return s + beta * x * s * (1.0 - s); + } + + fn batch_at(a: f32, b: f32, c: f32, index: usize) -> f32 { + var input : [3]f32 = [a, b, c]; + const output = forward_batch(&input, DEFAULT_BETA); + return output[index]; + } + + fn valid_input() -> f32 { + return 2.0; } // ═══════════════════════════════════════════════════════════ @@ -70,14 +84,14 @@ module SiluSwish; then result < 0.0 // SiLU(-1) = -1 * sigmoid(-1) < 0 test "forward_batch_basic_case" - given input = []f32{1.0, 2.0, 3.0}, beta = 1.0 - when result = forward_batch(input, beta) - then result.len == 3 // Should preserve array length + given beta = 1.0 + when result = batch_at(1.0, 2.0, 3.0, 2) + then @abs(result - forward(3.0, beta)) < 0.0000001 and @abs(batch_at(1.0, 2.0, 3.0, 0) - 0.7310586) < 0.000001 test "forward_batch_zero_case" - given input = []f32{0.0, 0.0, 0.0}, beta = 1.0 - when result = forward_batch(input, beta) - then result[0] == 0.0 and result[1] == 0.0 and result[2] == 0.0 // SiLU(0) = 0 + given beta = 1.0 + when result = batch_at(0.0, 0.0, 0.0, 0) + then result == 0.0 and batch_at(0.0, 0.0, 0.0, 1) == 0.0 and batch_at(0.0, 0.0, 0.0, 2) == 0.0 // SiLU(0) = 0 test "derivative_basic_case" given input = 0.0, beta = 1.0 @@ -98,23 +112,24 @@ module SiluSwish; // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // beta > 0 invariant silu_swish_constraint_0 - given input = valid_input() - then true // beta > 0 + assert DEFAULT_BETA > 0.0 + // name: silu_formula -- x * sigmoid(x), so SiLU(x) - SiLU(-x) = x invariant silu_swish_constraint_1 - given input = valid_input() - then true // name: silu_formula + assert @abs(forward(valid_input(), DEFAULT_BETA) - forward(-valid_input(), DEFAULT_BETA) - valid_input()) < 0.000001 + // name: derivative -- sigmoid(0) = 0.5 at the origin invariant silu_swish_constraint_2 - given input = valid_input() - then true // name: derivative + assert derivative(0.0, DEFAULT_BETA) == 0.5 + // "Elfwing et al. (2017) - Sigmoid-Weighted Linear Units for Neural Network Function Approximation": + // SiLU dips below zero left of the origin invariant silu_swish_constraint_3 - given input = valid_input() - then true // "Elfwing et al. (2017) - Sigmoid-Weighted Linear Units for Neural Network Function Approximation" + assert forward(-valid_input(), DEFAULT_BETA) < 0.0 + // "Ramachandran et al. (2017) - Searching for Activation Functions (Swish)": a large beta + // approaches ReLU invariant silu_swish_constraint_4 - given input = valid_input() - then true // "Ramachandran et al. (2017) - Searching for Activation Functions (Swish)" - + assert @abs(forward(valid_input(), 50.0) - valid_input()) < 0.000001 diff --git a/apps/website/public/t27/files/specs/ml/activation/softmax.t27 b/apps/website/public/t27/files/specs/ml/activation/softmax.t27 index e2f54c2128..859f9db7ed 100644 --- a/apps/website/public/t27/files/specs/ml/activation/softmax.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/softmax.t27 @@ -2,6 +2,11 @@ // t27/specs/ // Control sharpness of distribution | φ² + 1/φ² = 3 | TRINITY +// #8980: written with `range` and `math::exp`, which no spec declares, so no test +// ever ran. backward was also wrong: it used only the Jacobian's diagonal, +// p_i (1 - p_i), and dropped the -p_i p_j terms. It is now the full product +// grad_input_i = p_i (g_i - sum_j g_j p_j) / temperature. + module Softmax; use base::types; use math::constants; @@ -28,74 +33,134 @@ module Softmax; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(logits: []const f32, output: []f32, config: SoftmaxConfig) → void + // output_i = exp((x_i - max) / T) / sum_j exp((x_j - max) / T); subtracting the max keeps exp finite fn forward(logits: []const f32, output: []f32, config: SoftmaxConfig) -> void { - // Apply softmax transformation with temperature - var max_val: f32 = logits[0]; - for (i in range(logits.len)) { + var max_val : f32 = logits[0]; + var i : usize = 0; + while (i < logits.len) { if (logits[i] > max_val) { max_val = logits[i]; } + i = i + 1; } - - var sum: f32 = ZERO; - for (i in range(logits.len)) { - output[i] = math::exp((logits[i] - max_val) / config.temperature); - sum += output[i]; + var sum : f32 = ZERO; + i = 0; + while (i < logits.len) { + output[i] = exp((logits[i] - max_val) / config.temperature); + sum = sum + output[i]; + i = i + 1; } - - for (i in range(logits.len)) { - output[i] /= sum; + i = 0; + while (i < logits.len) { + output[i] = output[i] / sum; + i = i + 1; } } - // backward(grad_output: []const f32, probabilities: []const f32, grad_input: []f32, config: SoftmaxConfig) → void + // Vector-Jacobian product: grad_input_i = p_i (g_i - sum_j g_j p_j) / T fn backward(grad_output: []const f32, probabilities: []const f32, grad_input: []f32, config: SoftmaxConfig) -> void { - // Compute gradient of softmax loss - for (i in range(grad_output.len)) { - grad_input[i] = grad_output[i] * probabilities[i] * (ONE - probabilities[i]); + var dot : f32 = ZERO; + var i : usize = 0; + while (i < grad_output.len) { + dot = dot + grad_output[i] * probabilities[i]; + i = i + 1; + } + i = 0; + while (i < grad_output.len) { + grad_input[i] = probabilities[i] * (grad_output[i] - dot) / config.temperature; + i = i + 1; } } + fn cfg(temperature: f32) -> SoftmaxConfig { + return SoftmaxConfig{ .temperature = temperature, .axis = 0, .stable = true }; + } + + // output[index] of softmax over (a, b, c) + fn softmax_at(a: f32, b: f32, c: f32, temperature: f32, index: usize) -> f32 { + const logits : [3]f32 = [a, b, c]; + var output : [3]f32 = [0.0] ** 3; + forward(&logits, &output, cfg(temperature)); + return output[index]; + } + + // grad_input[index] for grad_output (0.1, 0.2, 0.3) at probabilities (0.2, 0.3, 0.5) + fn backward_at(index: usize) -> f32 { + const grad_output : [3]f32 = [0.1, 0.2, 0.3]; + const probabilities : [3]f32 = [0.2, 0.3, 0.5]; + var grad_input : [3]f32 = [0.0] ** 3; + backward(&grad_output, &probabilities, &grad_input, cfg(1.0)); + return grad_input[index]; + } + + // L = sum_i w_i softmax(x)_i with w = (0.1, 0.2, 0.3): the loss whose gradient backward computes + fn weighted(a: f32, b: f32, c: f32) -> f32 { + return 0.1 * softmax_at(a, b, c, 1.0, 0) + 0.2 * softmax_at(a, b, c, 1.0, 1) + 0.3 * softmax_at(a, b, c, 1.0, 2); + } + + fn grad_at(a: f32, b: f32, c: f32, index: usize) -> f32 { + const grad_output : [3]f32 = [0.1, 0.2, 0.3]; + var probabilities : [3]f32 = [0.0] ** 3; + const logits : [3]f32 = [a, b, c]; + forward(&logits, &probabilities, cfg(1.0)); + var grad_input : [3]f32 = [0.0] ** 3; + backward(&grad_output, &probabilities, &grad_input, cfg(1.0)); + return grad_input[index]; + } + + fn valid_input() -> f32 { + return 3.0; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // softmax(1, 2, 3) = (0.0900306, 0.2447285, 0.6652410) test "forward_basic_case" - given - logits = [1.0, 2.0, 3.0] - output = [0.0, 0.0, 0.0] - config = SoftmaxConfig { temperature = 1.0, axis = 0, stable = true } - when - forward(logits, output, config) - then - output[0] > 0.0 and output[1] > 0.0 and output[2] > 0.0 and - (output[0] + output[1] + output[2] - 1.0).abs() < 0.0001 - + given p0 = softmax_at(1.0, 2.0, 3.0, 1.0, 0) + when p2 = softmax_at(1.0, 2.0, 3.0, 1.0, 2) + then p0 > 0.0 and softmax_at(1.0, 2.0, 3.0, 1.0, 1) > 0.0 and p2 > 0.0 and @abs(p0 + softmax_at(1.0, 2.0, 3.0, 1.0, 1) + p2 - 1.0) < 0.0001 and @abs(p0 - 0.0900306) < 0.000001 and @abs(p2 - 0.6652410) < 0.000001 + + // Subtracting the max: logits of 1000 do not overflow exp + test "forward_large_logits_stay_finite" + given p = softmax_at(1000.0, 1000.0, 1000.0, 1.0, 1) + then @abs(p - 1.0 / 3.0) < 0.000001 + + // A higher temperature flattens the distribution toward uniform + test "forward_temperature_flattens" + given sharp = softmax_at(1.0, 2.0, 3.0, 1.0, 2) + when flat = softmax_at(1.0, 2.0, 3.0, 10.0, 2) + then flat < sharp and flat > 1.0 / 3.0 + + // dot = 0.23: grad = (0.2 (0.1 - 0.23), 0.3 (0.2 - 0.23), 0.5 (0.3 - 0.23)) = (-0.026, -0.009, 0.035) test "backward_basic_case" - given - grad_output = [0.1, 0.2, 0.3] - probabilities = [0.2, 0.3, 0.5] - grad_input = [0.0, 0.0, 0.0] - config = SoftmaxConfig { temperature = 1.0, axis = 0, stable = true } - when - backward(grad_output, probabilities, grad_input, config) - then - grad_input[0] != 0.0 and grad_input[1] != 0.0 and grad_input[2] != 0.0 + given g0 = backward_at(0) + when g2 = backward_at(2) + then g0 != 0.0 and backward_at(1) != 0.0 and g2 != 0.0 and @abs(g0 - (-0.026)) < 0.000001 and @abs(backward_at(1) - (-0.009)) < 0.000001 and @abs(g2 - 0.035) < 0.000001 + + // The gradient of a function of probabilities that sum to 1 sums to 0 + test "backward_sums_to_zero" + given total = backward_at(0) + backward_at(1) + backward_at(2) + then @abs(total) < 0.0000001 + + test "backward_matches_finite_difference" + given slope = (weighted(1.0, 2.0 + 0.001, 3.0) - weighted(1.0, 2.0 - 0.001, 3.0)) / 0.002 + when result = grad_at(1.0, 2.0, 3.0, 1) + then @abs(result - slope) < 0.0005 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // logits.size() == output.size(): the first and last element are both probabilities invariant softmax_constraint_0 - given input = valid_input() - then true // logits.size() == output.size() + assert softmax_at(1.0, 2.0, valid_input(), 1.0, 0) >= 0.0 and softmax_at(1.0, 2.0, valid_input(), 1.0, 2) >= 0.0 + // config.temperature >= MIN_TEMP invariant softmax_constraint_1 - given input = valid_input() - then true // config.temperature >= MIN_TEMP + assert cfg(1.0).temperature >= MIN_TEMP + // sum(output) = 1.0 within floating precision invariant softmax_constraint_2 - given input = valid_input() - then true // sum(output) ≈ 1.0 (within floating precision) - + assert @abs(softmax_at(1.0, 2.0, valid_input(), 1.0, 0) + softmax_at(1.0, 2.0, valid_input(), 1.0, 1) + softmax_at(1.0, 2.0, valid_input(), 1.0, 2) - 1.0) < 0.0001 diff --git a/apps/website/public/t27/files/specs/ml/activation/tanh_activation.t27 b/apps/website/public/t27/files/specs/ml/activation/tanh_activation.t27 index c96583f4f3..b6044c349c 100644 --- a/apps/website/public/t27/files/specs/ml/activation/tanh_activation.t27 +++ b/apps/website/public/t27/files/specs/ml/activation/tanh_activation.t27 @@ -2,6 +2,11 @@ // t27/specs/ // Derivative (can compute from output) | φ² + 1/φ² = 3 | TRINITY +// #8980: `math::exp` named a module this spec never imports, and +// forward_batch allocated with `[]f32{input.len}`. tanh is now computed in the +// form that cannot overflow: exp(2|x|) reaches inf in f32 at |x| = 45, and +// inf / inf is NaN. + module Tanh; use base::types; use math::constants; @@ -18,55 +23,62 @@ module Tanh; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(x: f32) → f32 + // tanh(x) = (1 - e^(-2|x|)) / (1 + e^(-2|x|)), with the sign of x fn forward(x: f32) -> f32 { - // tanh(x) = (e^x - e^-x) / (e^x + e^-x) - let exp_x = math::exp(x); - let exp_neg_x = math::exp(-x); - return (exp_x - exp_neg_x) / (exp_x + exp_neg_x); + if (x < 0.0) { + return -forward(-x); + } + const t = exp(-2.0 * x); + return (1.0 - t) / (1.0 + t); } - // forward_batch(input: []f32) → []f32 - fn forward_batch(input: []f32) -> []f32 { - let result = []f32{input.len}; - let mut i = 0; + // forward_batch: output[i] = tanh(input[i]) + fn forward_batch(input: []const f32, output: []f32) -> void { + var i : usize = 0; while (i < input.len) { - result[i] = forward(input[i]); + output[i] = forward(input[i]); i = i + 1; } - return result; } - // derivative(x: f32) → f32 + // tanh'(x) = 1 - tanh(x)^2 fn derivative(x: f32) -> f32 { - // tanh'(x) = 1 - tanh(x)² - let tanh_x = forward(x); + const tanh_x = forward(x); return 1.0 - (tanh_x * tanh_x); } - // derivative_from_output(tanh_x: f32) → f32 + // Given y = tanh(x), the derivative is 1 - y^2 fn derivative_from_output(tanh_x: f32) -> f32 { - // Given tanh(x), the derivative is 1 - tanh(x)² return 1.0 - (tanh_x * tanh_x); } + fn batch_at(index: usize) -> f32 { + const input : [3]f32 = [0.0, 1.0, 2.0]; + var output : [3]f32 = [0.0] ** 3; + forward_batch(&input, &output); + return output[index]; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // tanh(0) = 0, tanh(1) = 0.7615942, tanh is odd test forward_basic_case given input = 0.0 when result = forward(input) - then result == 0.0 + then result == 0.0 and @abs(forward(1.0) - 0.7615942) < 0.000001 and forward(-1.0) == -forward(1.0) + + // exp(2x) is inf in f32 here; the stable form still gives 1, not NaN + test forward_saturates_without_overflow + given input = 100.0 + when result = forward(input) + then result == 1.0 and forward(-100.0) == -1.0 test forward_batch_basic_case - given input = []f32{3, [0.0, 1.0, 2.0]} - when result = forward_batch(input) - then result.len == 3 - then result[0] == 0.0 - then result[1] > 0.0 - then result[1] < 1.0 - then result[2] > result[1] + given first = batch_at(0) + when second = batch_at(1) + then first == 0.0 and second > 0.0 and second < 1.0 and batch_at(2) > second test derivative_basic_case given input = 0.0 @@ -76,6 +88,9 @@ module Tanh; test derivative_from_output_basic_case given input = 0.5 when tanh_result = forward(input) - when result = derivative_from_output(tanh_result) - then result > 0.0 - then result < 1.0 \ No newline at end of file + then derivative_from_output(tanh_result) > 0.0 and derivative_from_output(tanh_result) < 1.0 and derivative_from_output(tanh_result) == derivative(input) + + test derivative_matches_finite_difference + given slope = (forward(0.5 + 0.001) - forward(0.5 - 0.001)) / 0.002 + when result = derivative(0.5) + then @abs(result - slope) < 0.001 diff --git a/apps/website/public/t27/files/specs/ml/layers/avgpool2d_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/avgpool2d_layer.t27 index 9429ac4c53..d542f5430a 100644 --- a/apps/website/public/t27/files/specs/ml/layers/avgpool2d_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/avgpool2d_layer.t27 @@ -2,6 +2,12 @@ // t27/specs/ // 2D average pooling formula | φ² + 1/φ² = 3 | TRINITY +// #8980: the kernel and stride were string constants typed `[]u32`, forward only +// asserted that its input was non-empty, and the tests asserted `true` or +// `result != undefined`. Average pooling now runs over one square H x H channel +// with the default 2 x 2 window and stride 2 and no padding, and each test checks +// numbers. + module Avgpool2d; use base::types; use math::constants; @@ -10,8 +16,8 @@ module Avgpool2d; // 1. Constants // ═══════════════════════════════════════════════════════════ - const DEFAULT_KERNEL : []u32 = "[2, 2]"; - const DEFAULT_STRIDE : []u32 = "[2, 2]"; + const DEFAULT_KERNEL : u32 = 2; + const DEFAULT_STRIDE : u32 = 2; // ═══════════════════════════════════════════════════════════ // 2. Types @@ -36,36 +42,110 @@ module Avgpool2d; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // calc_output_size(height_in: u32) → void - fn calc_output_size(height_in: u32) -> void { - // Calculate output dimensions for 2D average pooling - // Using default kernel size [2, 2], stride [2, 2], and padding [0, 0] - let kernel = DEFAULT_KERNEL; - let stride = DEFAULT_STRIDE; - let padding = [0u32, 0u32]; - - // Calculate output height and width - let height_out = (height_in + 2 * padding[0] - kernel[0]) / stride[0] + 1; - let width_out = (height_in + 2 * padding[1] - kernel[1]) / stride[1] + 1; - - // For now, just validate the calculation - assert(height_out > 0); - assert(width_out > 0); + // Output side for an input side n: (n - k) / stride + 1, and 0 when no window fits + fn calc_output_size(height_in: u32) -> u32 { + if (height_in < DEFAULT_KERNEL) { + return 0; + } + return (height_in - DEFAULT_KERNEL) / DEFAULT_STRIDE + 1; + } + + // output[oy][ox] = mean of the k x k window at (oy * stride, ox * stride) of a side x side + // input; returns the number of outputs written + fn forward(input: []const f32, side: u32, output: []f32) -> u32 { + const n = calc_output_size(side); + const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL)); + var oy : u32 = 0; + while (oy < n) { + var ox : u32 = 0; + while (ox < n) { + var sum : f32 = 0.0; + var ky : u32 = 0; + while (ky < DEFAULT_KERNEL) { + var kx : u32 = 0; + while (kx < DEFAULT_KERNEL) { + sum = sum + input[(oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx]; + kx = kx + 1; + } + ky = ky + 1; + } + output[oy * n + ox] = sum / area; + ox = ox + 1; + } + oy = oy + 1; + } + return n * n; + } + + // backward: each window's gradient is shared equally by its k * k inputs + fn backward(grad_output: []const f32, side: u32, grad_input: []f32) -> void { + const n = calc_output_size(side); + const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL)); + var i : usize = 0; + while (i < grad_input.len) { + grad_input[i] = 0.0; + i = i + 1; + } + var oy : u32 = 0; + while (oy < n) { + var ox : u32 = 0; + while (ox < n) { + var ky : u32 = 0; + while (ky < DEFAULT_KERNEL) { + var kx : u32 = 0; + while (kx < DEFAULT_KERNEL) { + const idx = (oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx; + grad_input[idx] = grad_input[idx] + grad_output[oy * n + ox] / area; + kx = kx + 1; + } + ky = ky + 1; + } + ox = ox + 1; + } + oy = oy + 1; + } + } + + // 4 x 4 input 0..15, row-major: windows average to 2.5, 4.5, 10.5, 12.5 + fn pool4_at(index: usize) -> f32 { + var input : [16]f32 = [0.0] ** 16; + var i : usize = 0; + while (i < 16) { + input[i] = @as(f32, @floatFromInt(i)); + i = i + 1; + } + var output : [4]f32 = [0.0] ** 4; + _ = forward(&input, 4, &output); + return output[index]; + } + + // forward over a 2 x 2 input (1, 2, 3, 4) or a 1 x 1 input (5); returns the outputs written + fn pool_count(side: u32) -> u32 { + const four : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + const one : [1]f32 = [5.0]; + var output : [1]f32 = [-1.0]; + if (side == 2) { + return forward(&four, 2, &output); + } + return forward(&one, 1, &output); + } + + fn pool2_value() -> f32 { + const four : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var output : [1]f32 = [-1.0]; + _ = forward(&four, 2, &output); + return output[0]; + } + + fn backward4_at(index: usize) -> f32 { + const grad_output : [4]f32 = [4.0, 8.0, 12.0, 16.0]; + var grad_input : [16]f32 = [9.0] ** 16; + backward(&grad_output, 4, &grad_input); + return grad_input[index]; } - // forward(input: []f32) → void - fn forward(input: []f32) -> void { - // Perform 2D average pooling operation - // Using default kernel size [2, 2], stride [2, 2], and padding [0, 0] - let kernel = DEFAULT_KERNEL; - let stride = DEFAULT_STRIDE; - let padding = [0u32, 0u32]; - - // For now, just validate the input - assert(input.len > 0); - - // TODO: Implement actual pooling logic from .tri spec - // This is a placeholder implementation + fn valid_input() -> u32 { + return calc_output_size(4); } // ═══════════════════════════════════════════════════════════ @@ -73,65 +153,70 @@ module Avgpool2d; // ═══════════════════════════════════════════════════════════ test calc_output_size_basic_case - given input = default_input() - when result = calc_output_size(input) - then result != undefined + given result = calc_output_size(4) + then result == 2 test calc_output_size_valid_input - given input = 10u32 + given input = 10 when result = calc_output_size(input) - then true // Function should complete without errors + then result == 5 + // A 1 x 1 input holds no 2 x 2 window test calc_output_size_small_input - given input = 1u32 + given input = 1 when result = calc_output_size(input) - then true // Function should handle minimal input size + then result == 0 and calc_output_size(2) == 1 test calc_output_size_large_input - given input = 1000u32 + given input = 1000 when result = calc_output_size(input) - then true // Function should handle large input size + then result == 500 and calc_output_size(1001) == 500 test forward_basic_case - given input = default_input() - when result = forward(input) - then result != undefined + given first = pool4_at(0) + when last = pool4_at(3) + then first == 2.5 and pool4_at(1) == 4.5 and pool4_at(2) == 10.5 and last == 12.5 + // A 2 x 2 input is one window: the mean of 1, 2, 3, 4 test forward_non_empty_input - given input = [1.0f32, 2.0f32, 3.0f32, 4.0f32] - when result = forward(input) - then true // Function should process valid input array + given count = pool_count(2) + when value = pool2_value() + then count == 1 and value == 2.5 test forward_single_element - given input = [5.0f32] - when result = forward(input) - then true // Function should handle single element input + given count = pool_count(1) + then count == 0 + + // Each of a window's 4 inputs gets a quarter of its gradient + test backward_spreads_the_gradient + given corner = backward4_at(0) + when last = backward4_at(15) + then corner == 1.0 and backward4_at(5) == 1.0 and backward4_at(2) == 2.0 and last == 4.0 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // kernel_size[i] >= 1 invariant avgpool2d_constraint_0 - given input = valid_input() - then true // kernel_size[i] >= 1 + assert DEFAULT_KERNEL >= 1 + // stride[i] >= 1 invariant avgpool2d_constraint_1 - given input = valid_input() - then true // stride[i] >= 1 + assert DEFAULT_STRIDE >= 1 + // stride[i] <= kernel_size[i]: windows tile the input without gaps invariant avgpool2d_constraint_2 - given input = valid_input() - then true // stride[i] <= kernel_size[i] + assert DEFAULT_STRIDE <= DEFAULT_KERNEL + // name: avgpool_formula -- (n - k) / s + 1 invariant avgpool2d_constraint_3 - given input = valid_input() - then true // name: avgpool_formula + assert valid_input() == 2 + // "Zeiler & Fergus (2014) - Visualizing and Understanding Convolutional Networks": pooling halves each side invariant avgpool2d_constraint_4 - given input = valid_input() - then true // "Zeiler & Fergus (2014) - Visualizing and Understanding Convolutional Networks" + assert calc_output_size(8) == 4 + // "He et al. (2016) - Deep Residual Learning for Image Recognition": a 7 x 7 map pools to 3 x 3 invariant avgpool2d_constraint_5 - given input = valid_input() - then true // "He et al. (2016) - Deep Residual Learning for Image Recognition" - + assert calc_output_size(7) == 3 diff --git a/apps/website/public/t27/files/specs/ml/layers/batchnorm_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/batchnorm_layer.t27 index a41052cc7d..e910bfe464 100644 --- a/apps/website/public/t27/files/specs/ml/layers/batchnorm_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/batchnorm_layer.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Prevent division by zero in sqrt | φ² + 1/φ² = 3 | TRINITY +// #8980: forward copied one element and backward zeroed two gradients +// (placeholders), and the tests pinned those placeholders: output[0] == input[0], +// grad_gamma[0] == grad_beta[0] == 0. They now compute batch normalisation: +// forward/backward in inference form, normalising by the running statistics, and +// forward_train normalising by the batch's own mean and variance. + module Batchnorm; use base::types; use math::constants; @@ -34,79 +40,166 @@ module Batchnorm; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32, gamma: []const f32, beta: []const f32, state: BatchNormState, output: []f32, config: BatchNormConfig) → void + // Inference: output[f] = gamma[f] (input[f] - running_mean[f]) / sqrt(running_var[f] + eps) + beta[f] fn forward(input: []const f32, gamma: []const f32, beta: []const f32, state: BatchNormState, output: []f32, config: BatchNormConfig) -> void { - // BatchNorm forward implementation - // Normalize input using running mean and variance, apply gamma and beta scaling - // Basic implementation - copy input to output - output[0] = input[0]; + var f : usize = 0; + while (f < config.num_features) { + const x_hat = (input[f] - state.running_mean[f]) / sqrt(state.running_var[f] + config.epsilon); + output[f] = gamma[f] * x_hat + beta[f]; + f = f + 1; + } } - // backward(grad_output: []const f32, input: []const f32, gamma: []const f32, beta: []const f32, mean: []const f32, var: []const f32, grad_gamma: []f32, grad_beta: []f32, grad_input: []f32, config: BatchNormConfig) → void + // Inference backward (mean and variance are constants here): + // grad_input[f] = grad_output[f] gamma[f] / sqrt(var[f] + eps) + // grad_gamma[f] = grad_output[f] x_hat[f], grad_beta[f] = grad_output[f] fn backward(grad_output: []const f32, input: []const f32, gamma: []const f32, beta: []const f32, mean: []const f32, var: []const f32, grad_gamma: []f32, grad_beta: []f32, grad_input: []f32, config: BatchNormConfig) -> void { - // BatchNorm backward implementation - // Compute gradients for gamma, beta, and input - // Basic implementation - initialize gradients - grad_gamma[0] = 0.0; - grad_beta[0] = 0.0; - grad_input[0] = grad_output[0] * gamma[0] / (sqrt(var[0]) + 1.0e-5); + var f : usize = 0; + while (f < config.num_features) { + const inv_std = 1.0 / sqrt(var[f] + config.epsilon); + grad_gamma[f] = grad_output[f] * (input[f] - mean[f]) * inv_std; + grad_beta[f] = grad_output[f]; + grad_input[f] = grad_output[f] * gamma[f] * inv_std; + f = f + 1; + } } - // ═══════════════════════════════════════════════════════════ - // TDD: Tests (from .tri behaviors) - // ═══════════════════════════════════════════════════════════ + // Training: input is batch x num_features, row-major. Each feature is normalised by + // its own batch mean and (biased) batch variance, then scaled and shifted. + fn forward_train(input: []const f32, batch: usize, gamma: []const f32, beta: []const f32, output: []f32, config: BatchNormConfig) -> void { + const nf : usize = config.num_features; + var f : usize = 0; + while (f < nf) { + var mean : f32 = 0.0; + var b : usize = 0; + while (b < batch) { + mean = mean + input[b * nf + f]; + b = b + 1; + } + mean = mean / @as(f32, @floatFromInt(batch)); + var variance : f32 = 0.0; + b = 0; + while (b < batch) { + const d = input[b * nf + f] - mean; + variance = variance + d * d; + b = b + 1; + } + variance = variance / @as(f32, @floatFromInt(batch)); + b = 0; + while (b < batch) { + output[b * nf + f] = gamma[f] * (input[b * nf + f] - mean) / sqrt(variance + config.epsilon) + beta[f]; + b = b + 1; + } + f = f + 1; + } + } + + fn cfg() -> BatchNormConfig { + return BatchNormConfig{ .num_features = 3, .epsilon = DEFAULT_EPSILON, .momentum = DEFAULT_MOMENTUM, .affine = true, .track_running_stats = true }; + } + + // forward on input (1, 2, 3), gamma g, beta 0.25, running mean 0 / var 1 (or mean 2 / var 4) + fn forward_at(g: f32, shifted: bool, index: usize) -> f32 { + const input : [3]f32 = [1.0, 2.0, 3.0]; + const gamma : [3]f32 = [g, g, g]; + const beta : [3]f32 = [0.25, 0.25, 0.25]; + var mean : [3]f32 = [0.0, 0.0, 0.0]; + var variance : [3]f32 = [1.0, 1.0, 1.0]; + if (shifted) { + mean = [2.0, 2.0, 2.0]; + variance = [4.0, 4.0, 4.0]; + } + const state = BatchNormState{ .running_mean = &mean, .running_var = &variance }; + var output : [3]f32 = [0.0] ** 3; + forward(&input, &gamma, &beta, state, &output, cfg()); + return output[index]; + } - test "forward_basic_case" { - var input = []f32{1.0, 2.0, 3.0}; - var gamma = []f32{1.0, 1.0, 1.0}; - var beta = []f32{0.0, 0.0, 0.0}; - var state = BatchNormState{running_mean = []f32{0.0, 0.0, 0.0}, running_var = []f32{1.0, 1.0, 1.0}}; - var output = []f32{0.0, 0.0, 0.0}; - var config = BatchNormConfig{num_features = 3, epsilon = 1.0e-5, momentum = 0.1, affine = true, track_running_stats = true}; - - forward(input, gamma, beta, state, output, config); - assert(output[0] == input[0]); + // which: 0 = grad_gamma, 1 = grad_beta, 2 = grad_input; grad_output 1, gamma 2, mean 0, var 1 + fn backward_at(which: u8, index: usize) -> f32 { + const grad_output : [3]f32 = [1.0, 1.0, 1.0]; + const input : [3]f32 = [1.0, 2.0, 3.0]; + const gamma : [3]f32 = [2.0, 2.0, 2.0]; + const beta : [3]f32 = [0.0, 0.0, 0.0]; + const mean : [3]f32 = [0.0, 0.0, 0.0]; + const variance : [3]f32 = [1.0, 1.0, 1.0]; + var grad_gamma : [3]f32 = [9.0] ** 3; + var grad_beta : [3]f32 = [9.0] ** 3; + var grad_input : [3]f32 = [9.0] ** 3; + backward(&grad_output, &input, &gamma, &beta, &mean, &variance, &grad_gamma, &grad_beta, &grad_input, cfg()); + if (which == 0) { + return grad_gamma[index]; + } + if (which == 1) { + return grad_beta[index]; + } + return grad_input[index]; } - test "backward_basic_case" { - var grad_output = []f32{1.0, 1.0, 1.0}; - var input = []f32{1.0, 2.0, 3.0}; - var gamma = []f32{1.0, 1.0, 1.0}; - var beta = []f32{0.0, 0.0, 0.0}; - var mean = []f32{0.0, 0.0, 0.0}; - var var = []f32{1.0, 1.0, 1.0}; - var grad_gamma = []f32{0.0, 0.0, 0.0}; - var grad_beta = []f32{0.0, 0.0, 0.0}; - var grad_input = []f32{0.0, 0.0, 0.0}; - var config = BatchNormConfig{num_features = 3, epsilon = 1.0e-5, momentum = 0.1, affine = true, track_running_stats = true}; - - backward(grad_output, input, gamma, beta, mean, var, grad_gamma, grad_beta, grad_input, config); - assert(grad_gamma[0] == 0.0); - assert(grad_beta[0] == 0.0); - assert(grad_input[0] != 0.0); + // forward_train on a batch of 4 samples x 3 features; returns output[b][f] + fn train_at(b: usize, f: usize) -> f32 { + const input : [12]f32 = [1.0, 10.0, -1.0, 2.0, 20.0, -1.0, 3.0, 30.0, 1.0, 4.0, 40.0, 1.0]; + const gamma : [3]f32 = [1.0, 1.0, 1.0]; + const beta : [3]f32 = [0.0, 0.0, 0.0]; + var output : [12]f32 = [0.0] ** 12; + forward_train(&input, 4, &gamma, &beta, &output, cfg()); + return output[b * 3 + f]; } + fn valid_input() -> u32 { + return cfg().num_features; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // With mean 0, var 1, gamma 1, beta 0 the layer is the identity up to eps: + // 1 / sqrt(1 + 1e-5) = 0.999995 (the old `==` held only for the copy placeholder) + test "forward_basic_case" + given out0 = forward_at(1.0, false, 0) - 0.25 + when out2 = forward_at(1.0, false, 2) - 0.25 + then @abs(out0 - 1.0) < 0.00001 and @abs(out2 - 3.0) < 0.00003 + + // mean 2, var 4: (x - 2) / 2 * gamma + beta, so x = 3 with gamma 2 gives 1.25 + test "forward_uses_running_statistics" + given result = forward_at(2.0, true, 2) + when centre = forward_at(2.0, true, 1) + then @abs(result - 1.25) < 0.00001 and centre == 0.25 + + // grad_gamma = g x_hat = (1, 2, 3) / sqrt(1 + eps), grad_beta = g = 1, + // grad_input = g gamma / sqrt(1 + eps) = 2 (the old 0, 0 were the placeholder's) + test "backward_basic_case" + given grad_gamma = backward_at(0, 2) + when grad_input = backward_at(2, 0) + then @abs(grad_gamma - 3.0) < 0.0001 and backward_at(1, 0) == 1.0 and grad_input != 0.0 and @abs(grad_input - 2.0) < 0.0001 + + // Each feature of the batch comes out with mean 0 and variance 1 + test "forward_train_normalises_each_feature" + given mean_f1 = train_at(0, 1) + train_at(1, 1) + train_at(2, 1) + train_at(3, 1) + when var_f1 = (train_at(0, 1) * train_at(0, 1) + train_at(1, 1) * train_at(1, 1) + train_at(2, 1) * train_at(2, 1) + train_at(3, 1) * train_at(3, 1)) / 4.0 + then @abs(mean_f1) < 0.00001 and @abs(var_f1 - 1.0) < 0.0001 and @abs(train_at(0, 0) - train_at(0, 1)) < 0.00001 and @abs(train_at(0, 2) + 1.0) < 0.0001 + // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // num_features > 0 invariant batchnorm_constraint_0 - given input = valid_input() - then true // num_features > 0 + assert valid_input() > 0 + // epsilon > 0 invariant batchnorm_constraint_1 - given input = valid_input() - then true // epsilon > 0 + assert DEFAULT_EPSILON > 0.0 + // 0 <= momentum < 1 invariant batchnorm_constraint_2 - given input = valid_input() - then true // 0 <= momentum < 1 + assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0 + // gamma.size() == num_features: the fixtures carry 3 of each invariant batchnorm_constraint_3 - given input = valid_input() - then true // gamma.size() == num_features + assert valid_input() == 3 + // beta.size() == num_features: beta shifts every feature, so x = mean gives exactly beta invariant batchnorm_constraint_4 - given input = valid_input() - then true // beta.size() == num_features - + assert forward_at(2.0, true, 1) == 0.25 diff --git a/apps/website/public/t27/files/specs/ml/layers/dense_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/dense_layer.t27 index be1b0d3274..a75924f73d 100644 --- a/apps/website/public/t27/files/specs/ml/layers/dense_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/dense_layer.t27 @@ -2,6 +2,11 @@ // t27/specs/ // Row-major weight layout for cache efficiency | φ² + 1/φ² = 3 | TRINITY +// #8980: forward and backward were empty placeholders, the tests asserted +// `result != undefined`, and the invariants asserted `true` over an undeclared +// `valid_input`. Dense is now y = act(W x + b) with W row-major +// (output_size x input_size), and backward gives the three gradients. + module Dense; use base::types; use math::constants; @@ -37,67 +42,173 @@ module Dense; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32) → void - fn forward(input: []const f32) -> void { - // Dense layer forward pass: output = activation(input * weights + bias) - // Simple placeholder implementation - just validate input and return - _ = input; // Prevent unused parameter warning - return; // Actual executable statement + // relu, the one activation the tests exercise besides None + fn activate(z: f32, activation: ActivationType) -> f32 { + if (activation == ActivationType.ReLU) { + if (z > 0.0) { + return z; + } + return 0.0; + } + return z; + } + + // output[o] = act(sum_i weights[o * in + i] * input[i] + bias[o]) + fn forward(input: []const f32, weights: []const f32, bias: []const f32, config: DenseConfig, output: []f32) -> void { + var o : usize = 0; + while (o < config.output_size) { + var z : f32 = 0.0; + if (config.has_bias) { + z = bias[o]; + } + var i : usize = 0; + while (i < config.input_size) { + z = z + weights[o * config.input_size + i] * input[i]; + i = i + 1; + } + output[o] = activate(z, config.activation); + o = o + 1; + } + } + + // For a linear layer (activation None), given dL/dy = grad_output: + // grad_input[i] = sum_o W[o][i] grad_output[o] (W^T g) + // grad_weights[o][i] = grad_output[o] * input[i] (g x^T) + // grad_bias[o] = grad_output[o] + fn backward(grad_output: []const f32, input: []const f32, weights: []const f32, config: DenseConfig, grad_input: []f32, grad_weights: []f32, grad_bias: []f32) -> void { + var i : usize = 0; + while (i < config.input_size) { + grad_input[i] = 0.0; + i = i + 1; + } + var o : usize = 0; + while (o < config.output_size) { + grad_bias[o] = grad_output[o]; + i = 0; + while (i < config.input_size) { + grad_input[i] = grad_input[i] + weights[o * config.input_size + i] * grad_output[o]; + grad_weights[o * config.input_size + i] = grad_output[o] * input[i]; + i = i + 1; + } + o = o + 1; + } + } + + // The fixture: 3 inputs, 2 outputs, W = [[1, 2, 3], [-1, 0, 1]], b = [0.5, -0.5] + fn cfg(activation: ActivationType) -> DenseConfig { + return DenseConfig{ .input_size = 3, .output_size = 2, .has_bias = true, .activation = activation }; + } + + fn forward_at(x0: f32, x1: f32, x2: f32, activation: ActivationType, index: usize) -> f32 { + const input : [3]f32 = [x0, x1, x2]; + const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0]; + const bias : [2]f32 = [0.5, -0.5]; + var output : [2]f32 = [0.0] ** 2; + forward(&input, &weights, &bias, cfg(activation), &output); + return output[index]; + } + + // L = g . y for g = (g0, g1): the loss whose gradients backward computes + fn loss_at(x0: f32, x1: f32, x2: f32, g0: f32, g1: f32) -> f32 { + return g0 * forward_at(x0, x1, x2, ActivationType.None, 0) + g1 * forward_at(x0, x1, x2, ActivationType.None, 1); + } + + // which: 0 = grad_input, 1 = grad_weights, 2 = grad_bias + fn backward_at(g0: f32, g1: f32, which: u8, index: usize) -> f32 { + const grad_output : [2]f32 = [g0, g1]; + const input : [3]f32 = [1.0, 2.0, 3.0]; + const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0]; + var grad_input : [3]f32 = [9.0] ** 3; + var grad_weights : [6]f32 = [9.0] ** 6; + var grad_bias : [2]f32 = [9.0] ** 2; + backward(&grad_output, &input, &weights, cfg(ActivationType.None), &grad_input, &grad_weights, &grad_bias); + if (which == 0) { + return grad_input[index]; + } + if (which == 1) { + return grad_weights[index]; + } + return grad_bias[index]; + } + + // An empty layer (no inputs, no outputs) writes nothing + fn empty_forward_untouched() -> bool { + const none : [0]f32 = []; + var sentinel : [1]f32 = [7.0]; + const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None }; + forward(&none, &none, &none, empty_cfg, &sentinel); + return sentinel[0] == 7.0; } - // backward(grad_output: []const f32) → void - fn backward(grad_output: []const f32) -> void { - // Dense layer backward pass: compute gradients through the layer - // Simple placeholder implementation - just validate gradient and return - _ = grad_output; // Prevent unused parameter warning - return; // Actual executable statement + fn empty_backward_untouched() -> bool { + const none : [0]f32 = []; + var sentinel : [1]f32 = [7.0]; + const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None }; + backward(&none, &none, &none, empty_cfg, &sentinel, &sentinel, &sentinel); + return sentinel[0] == 7.0; + } + + fn valid_input() -> f32 { + return forward_at(1.0, 2.0, 3.0, ActivationType.None, 0); } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // x = (1, 2, 3): y0 = 1 + 4 + 9 + 0.5 = 14.5, y1 = -1 + 0 + 3 - 0.5 = 1.5 test forward_basic_case - given input = [1.0f32, 2.0f32, 3.0f32] // 3-element input vector - when result = forward(input) - then result != undefined // Function should complete without crashing + given y0 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 0) + when y1 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 1) + then y0 == 14.5 and y1 == 1.5 + + // ReLU clips the negative pre-activation: x = (0, 0, -1) gives y = (-2.5, -1.5) -> (0, 0) + test forward_relu_clips_negatives + given linear = forward_at(0.0, 0.0, -1.0, ActivationType.None, 0) + when clipped = forward_at(0.0, 0.0, -1.0, ActivationType.ReLU, 0) + then linear == -2.5 and clipped == 0.0 and forward_at(1.0, 2.0, 3.0, ActivationType.ReLU, 0) == 14.5 test forward_empty_input - given input = []f32 // Empty input - when result = forward(input) - then result != undefined // Should handle empty input gracefully + given result = empty_forward_untouched() + then result + // g = (1, 2): grad_input = W^T g = (1 - 2, 2 + 0, 3 + 2) = (-1, 2, 5); grad_bias = g; + // grad_weights[1][2] = g1 * x2 = 6 test backward_basic_case - given grad_output = [0.5f32, -0.3f32, 0.8f32] // 3-element gradient vector - when result = backward(grad_output) - then result != undefined // Function should complete without crashing + given gi0 = backward_at(1.0, 2.0, 0, 0) + when gi2 = backward_at(1.0, 2.0, 0, 2) + then gi0 == -1.0 and backward_at(1.0, 2.0, 0, 1) == 2.0 and gi2 == 5.0 and backward_at(1.0, 2.0, 2, 1) == 2.0 and backward_at(1.0, 2.0, 1, 5) == 6.0 + + // dL/dx1 by finite difference equals grad_input[1] + test backward_matches_finite_difference + given slope = (loss_at(1.0, 2.0 + 0.01, 3.0, 1.0, 2.0) - loss_at(1.0, 2.0 - 0.01, 3.0, 1.0, 2.0)) / 0.02 + when result = backward_at(1.0, 2.0, 0, 1) + then @abs(result - slope) < 0.001 test backward_empty_gradient - given grad_output = []f32 // Empty gradient - when result = backward(grad_output) - then result != undefined // Should handle empty gradient gracefully + given result = empty_backward_untouched() + then result // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // input.size() == config.input_size: the bounds the layer accepts invariant dense_constraint_0 - given input = valid_input() - then true // input.size() == config.input_size + assert MIN_INPUT_SIZE >= 1 and MAX_INPUT_SIZE >= MIN_INPUT_SIZE + // output.size() == config.output_size: each output is one row of W x + b invariant dense_constraint_1 - given input = valid_input() - then true // output.size() == config.output_size + assert valid_input() == 14.5 + // weights.size() == input_size * output_size: the fixture holds 3 * 2 = 6 weights invariant dense_constraint_2 - given input = valid_input() - then true // weights.size() == input_size * output_size + assert cfg(ActivationType.None).input_size * cfg(ActivationType.None).output_size == 6 + // bias.size() == output_size (if has_bias): the fixture carries a bias of 2 invariant dense_constraint_3 - given input = valid_input() - then true // bias.size() == output_size (if has_bias) + assert cfg(ActivationType.None).has_bias + // All inputs must be finite (no NaN/Inf): finite in, finite out invariant dense_constraint_4 - given input = valid_input() - then true // All inputs must be finite (no NaN/Inf) - + assert valid_input() == valid_input() diff --git a/apps/website/public/t27/files/specs/ml/layers/dropout_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/dropout_layer.t27 index 3b09f5e000..4a12f21501 100644 --- a/apps/website/public/t27/files/specs/ml/layers/dropout_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/dropout_layer.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Prevent co-adaptation of neurons | φ² + 1/φ² = 3 | TRINITY +// #8980: the tests called `allocf32` and `allocbool`, which no spec declares, and +// asserted `result != undefined`. Inference also scaled by (1 - p) even for +// inverted dropout, which already scaled by 1 / (1 - p) in training, so the +// expected activation shrank by (1 - p) between training and inference. Inference +// is now the identity when scale_during_training is set. + module Dropout; use base::types; use math::constants; @@ -44,8 +50,13 @@ module Dropout; output[i] = 0.0; } } else { - // During inference, always scale output - output[i] = input[i] * (1.0 - config.p); + if (config.scale_during_training) { + // Inverted dropout already scaled in training: inference is the identity + output[i] = input[i]; + } else { + // Classic dropout: scale by the keep probability at inference + output[i] = input[i] * (1.0 - config.p); + } } i = i + 1; } @@ -75,19 +86,48 @@ module Dropout; // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + fn cfg(scaled: bool) -> DropoutConfig { + return DropoutConfig{ .p = DEFAULT_DROP_RATE, .inplace = false, .scale_during_training = scaled }; + } + + // forward on input (1, 2, 3, 4) with mask (keep, drop, keep, drop) + fn forward_at(training: bool, scaled: bool, index: usize) -> f32 { + const input : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var output : [4]f32 = [9.0] ** 4; + var mask : [4]bool = [true, false, true, false]; + forward(&input, &output, &mask, training, cfg(scaled)); + return output[index]; + } + + fn backward_at(scaled: bool, index: usize) -> f32 { + const grad_output : [4]f32 = [1.0, 1.0, 1.0, 1.0]; + const mask : [4]bool = [true, false, true, false]; + var grad_input : [4]f32 = [9.0] ** 4; + backward(&grad_output, &mask, &grad_input, cfg(scaled)); + return grad_input[index]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // p = 0.5, inverted: kept units are doubled, dropped ones are 0 test forward_basic_case - given input = default_input() - output = allocf32(input.len) - mask = allocbool(input.len) - config = DropoutConfig { p = 0.5, inplace = false, scale_during_training = true } - when result = forward(input, output, mask, true, config) - then result != undefined + given kept = forward_at(true, true, 2) + when dropped = forward_at(true, true, 1) + then kept == 6.0 and dropped == 0.0 and forward_at(true, true, 0) == 2.0 + + // The expected activation is the same in training and inference + test forward_inference_keeps_the_expectation + given inverted = forward_at(false, true, 2) + when classic = forward_at(false, false, 2) + then inverted == 3.0 and classic == 1.5 and forward_at(true, false, 2) == 3.0 + // The gradient flows only through kept units, with the same scale test backward_basic_case - given grad_output = default_input() - mask = allocbool(grad_output.len) - grad_input = allocf32(grad_output.len) - config = DropoutConfig { p = 0.5, inplace = false, scale_during_training = true } - when result = backward(grad_output, mask, grad_input, config) - then result != undefined + given kept = backward_at(true, 0) + when dropped = backward_at(true, 3) + then kept == 2.0 and dropped == 0.0 and backward_at(false, 2) == 1.0 + invariant dropout_rate_is_a_probability + assert DEFAULT_DROP_RATE >= 0.0 and DEFAULT_DROP_RATE < 1.0 diff --git a/apps/website/public/t27/files/specs/ml/layers/embedding_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/embedding_layer.t27 index 4ed89feeeb..836fe230b7 100644 --- a/apps/website/public/t27/files/specs/ml/layers/embedding_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/embedding_layer.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Embeddings are learned parameters | φ² + 1/φ² = 3 | TRINITY +// #8980: forward only asserted its arguments and wrote nothing, the tests called +// undeclared `test_input_forward` / `test_input_init` and asserted +// `result != undefined`, and the invariants asserted `true`. forward now looks each +// token's row up in W (vocab_size x d_model, row-major), backward adds each +// gradient row back into the row it came from, and init fills W deterministically. + module Embedding; use base::types; use math::constants; @@ -29,76 +35,131 @@ module Embedding; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(token_ids: []const u32, weights: EmbeddingWeights, embeddings: []f32, config: EmbeddingConfig) → void + // embeddings[t * d + j] = W[token_ids[t] * d + j]: one row of W per token fn forward(token_ids: []const u32, weights: EmbeddingWeights, embeddings: []f32, config: EmbeddingConfig) -> void { - // Validate input parameters - assert(config.vocab_size > 0); - assert(config.d_model > 0); - assert(weights.W.size() == config.vocab_size * config.d_model); - - // Basic implementation: validate all token IDs are in range - for (i in token_ids) { - assert(i < config.vocab_size); + const d : usize = config.d_model; + var t : usize = 0; + while (t < token_ids.len) { + const row : usize = token_ids[t]; + var j : usize = 0; + while (j < d) { + embeddings[t * d + j] = weights.W[row * d + j]; + j = j + 1; + } + t = t + 1; } } - // init(weights: EmbeddingWeights, config: EmbeddingConfig) → void + // grad_W[token_ids[t]] += grad_embeddings[t]: a token seen twice collects both rows + fn backward(token_ids: []const u32, grad_embeddings: []const f32, grad_W: []f32, config: EmbeddingConfig) -> void { + const d : usize = config.d_model; + var t : usize = 0; + while (t < token_ids.len) { + const row : usize = token_ids[t]; + var j : usize = 0; + while (j < d) { + grad_W[row * d + j] = grad_W[row * d + j] + grad_embeddings[t * d + j]; + j = j + 1; + } + t = t + 1; + } + } + + // Deterministic init in [-0.5, 0.5) / sqrt(d_model): a fixed hash of (row, column), so + // two runs start from the same weights fn init(weights: EmbeddingWeights, config: EmbeddingConfig) -> void { - // Validate configuration - assert(config.vocab_size > 0); - assert(config.d_model > 0); - - // Initialize weight matrix with appropriate size - let expected_size: u32 = config.vocab_size * config.d_model; - assert(weights.W.size() == expected_size); - - // Basic validation - weights array is properly sized - assert(weights.W.size() > 0); + const d : usize = config.d_model; + const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d))); + var k : usize = 0; + while (k < config.vocab_size * d) { + const h : u32 = @as(u32, @intCast((k * 2654435761) % 1000)); + weights.W[k] = (@as(f32, @floatFromInt(h)) / 1000.0 - 0.5) * scale; + k = k + 1; + } + } + + // vocab 4, d_model 2, W row v = (10 v, 10 v + 1) + fn cfg() -> EmbeddingConfig { + return EmbeddingConfig{ .vocab_size = 4, .d_model = 2 }; + } + + fn lookup_at(a: u32, b: u32, index: usize) -> f32 { + var w : [8]f32 = [0.0, 1.0, 10.0, 11.0, 20.0, 21.0, 30.0, 31.0]; + const ids : [2]u32 = [a, b]; + var out : [4]f32 = [-1.0] ** 4; + forward(&ids, EmbeddingWeights{ .W = &w }, &out, cfg()); + return out[index]; + } + + // grad_W[index] after backward of ids (a, b) with gradient rows (1, 2) and (3, 4) + fn grad_at(a: u32, b: u32, index: usize) -> f32 { + const ids : [2]u32 = [a, b]; + const grads : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var grad_w : [8]f32 = [0.0] ** 8; + backward(&ids, &grads, &grad_w, cfg()); + return grad_w[index]; + } + + fn init_at(index: usize) -> f32 { + var w : [8]f32 = [9.0] ** 8; + init(EmbeddingWeights{ .W = &w }, cfg()); + return w[index]; + } + + fn valid_input() -> u32 { + return cfg().vocab_size * cfg().d_model; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // ids (2, 0): rows (20, 21) then (0, 1) test forward_basic_case - given input = test_input_forward() - when result = forward(input) - then result != undefined + given first = lookup_at(2, 0, 0) + when last = lookup_at(2, 0, 3) + then first == 20.0 and lookup_at(2, 0, 1) == 21.0 and lookup_at(2, 0, 2) == 0.0 and last == 1.0 + // Every weight is written, inside [-0.5, 0.5) / sqrt(2), and init is reproducible test init_basic_case - given input = test_input_init() - when result = init(input) - then result != undefined + given first = init_at(0) + when last = init_at(7) + then first != 9.0 and last != 9.0 and @abs(first) <= 0.36 and @abs(last) <= 0.36 and init_at(5) == init_at(5) and init_at(1) != init_at(2) + + // A token seen twice collects both gradient rows; an unseen row stays 0 + test backward_accumulates_repeated_tokens + given row1 = grad_at(1, 1, 2) + when unseen = grad_at(1, 1, 0) + then row1 == 4.0 and grad_at(1, 1, 3) == 6.0 and unseen == 0.0 and grad_at(1, 3, 6) == 3.0 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // vocab_size > 0 invariant embedding_constraint_0 - given input = valid_input() - then true // vocab_size > 0 + assert cfg().vocab_size > 0 + // d_model > 0 invariant embedding_constraint_1 - given input = valid_input() - then true // d_model > 0 + assert cfg().d_model > 0 and DEFAULT_D_MODEL > 0 + // W.size() == vocab_size * d_model invariant embedding_constraint_2 - given input = valid_input() - then true // W.size() == vocab_size * d_model + assert valid_input() == 8 + // token_ids must be in [0, vocab_size): the last id reads the last row invariant embedding_constraint_3 - given input = valid_input() - then true // token_ids must be in [0, vocab_size) + assert lookup_at(3, 3, 1) == 31.0 + // "Embedding dimension affects model capacity": each token gets d_model numbers invariant embedding_constraint_4 - given input = valid_input() - then true // "Embedding dimension affects model capacity" + assert lookup_at(1, 2, 1) == 11.0 and lookup_at(1, 2, 2) == 20.0 + // "Larger vocab requires larger d_model": the init scale shrinks as 1 / sqrt(d_model) invariant embedding_constraint_5 - given input = valid_input() - then true // "Larger vocab requires larger d_model" + assert 1.0 / sqrt(@as(f32, 64.0)) < 1.0 / sqrt(@as(f32, 2.0)) + // "Pre-trained embeddings transfer well": forward is a pure lookup, so loaded rows come out unchanged invariant embedding_constraint_6 - given input = valid_input() - then true // "Pre-trained embeddings transfer well" - + assert lookup_at(0, 1, 0) == 0.0 and lookup_at(0, 1, 2) == 10.0 diff --git a/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 index f73b9ddab9..6841238ca8 100644 --- a/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 @@ -2,6 +2,13 @@ // t27/specs/ // Reduce spatial dimensions | φ² + 1/φ² = 3 | TRINITY +// #8980: forward and backward compared two values and threw them away +// (placeholders), and every test asserted `result != undefined`. Max pooling now +// runs over one H x W channel (row-major) with a k x k window and a stride. It +// records each window's argmax, and backward sends each gradient back to that +// element only. Padding and dilation are carried in the config but not read: the +// layer assumes padding 0 and dilation 1. + module Maxpool2d; use base::types; use math::constants; @@ -22,81 +29,119 @@ module Maxpool2d; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32) → void - fn forward(input: []const f32) -> void { - // Max pooling forward pass: find maximum values in each window - // Simple implementation that processes input data - const input_size : u32 = @truncate(input.len); - - // Basic max pooling logic - process first few elements as example - if (input_size > 1) { - const val1 : f32 = input[0]; - const val2 : f32 = input[1]; - - // Simple max operation - if (val1 > val2) { - _ = val1; // Store max value (simplified) - } else { - _ = val2; // Store max value (simplified) - } - } - - if (input_size > 3) { - const val3 : f32 = input[2]; - const val4 : f32 = input[3]; - - // Simple max operation - if (val3 > val4) { - _ = val3; // Store max value (simplified) - } else { - _ = val4; // Store max value (simplified) + // Output side for an input side n: (n - k) / stride + 1 + fn out_size(n: u32, config: MaxPool2DConfig) -> u32 { + return (n - config.kernel_size) / config.stride + 1; + } + + // output[oy][ox] = max of the k x k window at (oy * stride, ox * stride); + // indices[oy][ox] = the flat input index that held it + fn forward(input: []const f32, height: u32, width: u32, config: MaxPool2DConfig, output: []f32, indices: []u32) -> void { + const oh = out_size(height, config); + const ow = out_size(width, config); + var oy : u32 = 0; + while (oy < oh) { + var ox : u32 = 0; + while (ox < ow) { + var best_index : u32 = (oy * config.stride) * width + ox * config.stride; + var ky : u32 = 0; + while (ky < config.kernel_size) { + var kx : u32 = 0; + while (kx < config.kernel_size) { + const idx : u32 = (oy * config.stride + ky) * width + ox * config.stride + kx; + if (input[idx] > input[best_index]) { + best_index = idx; + } + kx = kx + 1; + } + ky = ky + 1; + } + output[oy * ow + ox] = input[best_index]; + indices[oy * ow + ox] = best_index; + ox = ox + 1; } + oy = oy + 1; } } - // backward(grad_output: []const f32) → void - fn backward(grad_output: []const f32) -> void { - // Max pooling backward pass: propagate gradients to input - // Simple implementation that processes gradient data - const grad_size : u32 = @truncate(grad_output.len); - - // Basic gradient propagation logic - process first few elements as example - if (grad_size > 0) { - const grad1 : f32 = grad_output[0]; - _ = grad1; // Process gradient value (simplified) + // grad_input[indices[o]] += grad_output[o]; every other input gets 0 + fn backward(grad_output: []const f32, indices: []const u32, grad_input: []f32) -> void { + var i : usize = 0; + while (i < grad_input.len) { + grad_input[i] = 0.0; + i = i + 1; } - - if (grad_size > 1) { - const grad2 : f32 = grad_output[1]; - _ = grad2; // Process gradient value (simplified) + var o : usize = 0; + while (o < grad_output.len) { + grad_input[indices[o]] = grad_input[indices[o]] + grad_output[o]; + o = o + 1; } } + fn cfg(kernel: u32, stride: u32) -> MaxPool2DConfig { + return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; + } + + // The 4 x 4 fixture + // 1 2 5 6 + // 3 4 8 7 + // 0 -1 -3 -2 + // -4 9 -6 -5 + fn pool_at(kernel: u32, stride: u32, which: u8, index: usize) -> f32 { + const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0]; + var output : [9]f32 = [0.0] ** 9; + var indices : [9]u32 = [0] ** 9; + forward(&input, 4, 4, cfg(kernel, stride), &output, &indices); + if (which == 0) { + return output[index]; + } + return @as(f32, @floatFromInt(indices[index])); + } + + // 2 x 2, stride 2, gradients (1, 2, 3, 4) for the four windows; grad_input[index] + fn backward_at(index: usize) -> f32 { + const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0]; + var output : [4]f32 = [0.0] ** 4; + var indices : [4]u32 = [0] ** 4; + forward(&input, 4, 4, cfg(2, 2), &output, &indices); + const grad_output : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var grad_input : [16]f32 = [9.0] ** 16; + backward(&grad_output, &indices, &grad_input); + return grad_input[index]; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // 2 x 2, stride 2: windows' maxima are 4, 8, 9, -2 test forward_basic_case - given input = default_input() - when result = forward(input) - then result != undefined - then input.len > 0 // Input should not be empty - - test backward_basic_case - given grad_output = [1.0, 2.0, 3.0, 4.0] // Sample gradient output - when result = backward(grad_output) - then result != undefined - then grad_output.len > 0 // Gradient input should not be empty + given first = pool_at(2, 2, 0, 0) + when last = pool_at(2, 2, 0, 3) + then first == 4.0 and pool_at(2, 2, 0, 1) == 8.0 and pool_at(2, 2, 0, 2) == 9.0 and last == -2.0 + // The argmax indices: 4 at 5, 8 at 6, 9 at 13, -2 at 11 test forward_max_finding - given input = [1.0, 2.0, 3.0, 4.0] // 2x2 input - when result = forward(input) - then result != undefined - // Should find max values in each window + given first = pool_at(2, 2, 1, 0) + when third = pool_at(2, 2, 1, 2) + then first == 5.0 and pool_at(2, 2, 1, 1) == 6.0 and third == 13.0 and pool_at(2, 2, 1, 3) == 11.0 + + // 3 x 3, stride 1 gives a 2 x 2 output whose windows overlap + test forward_overlapping_windows + given first = pool_at(3, 1, 0, 0) + when last = pool_at(3, 1, 0, 3) + then first == 8.0 and pool_at(3, 1, 0, 1) == 8.0 and pool_at(3, 1, 0, 2) == 9.0 and last == 9.0 + + test backward_basic_case + given at_max = backward_at(5) + when elsewhere = backward_at(0) + then at_max == 1.0 and elsewhere == 0.0 + // Each window's gradient lands on its argmax only: the sum is conserved test backward_gradient_propagation - given grad_output = [0.5, 1.0] // Sample gradients - when result = backward(grad_output) - then result != undefined - // Should properly propagate gradients + given total = backward_at(5) + backward_at(6) + backward_at(13) + backward_at(11) + when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) + then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + invariant maxpool_output_size_formula + assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2 diff --git a/apps/website/public/t27/files/specs/ml/loss/binary_crossentropy_loss.t27 b/apps/website/public/t27/files/specs/ml/loss/binary_crossentropy_loss.t27 index 5f398bb75a..063ee794ce 100644 --- a/apps/website/public/t27/files/specs/ml/loss/binary_crossentropy_loss.t27 +++ b/apps/website/public/t27/files/specs/ml/loss/binary_crossentropy_loss.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Gradient w.r.t predictions | φ² + 1/φ² = 3 | TRINITY +// #8980: never compiled (`new f32[n]`, a float loop index, `predictions.size`, +// an empty enum), and it approximated sigmoid and log with polynomials that +// were 0.3 off at x = 1. The probability gradient also had the wrong sign on its +// second term: d/dp of -(t log p + (1-t) log(1-p)) is -t/p + (1-t)/(1-p). It now +// uses exp and log, writes gradients into a caller's buffer, and reduces by mean. + module BinaryCe; use base::types; use math::constants; @@ -22,168 +28,114 @@ module BinaryCe; reduction : Reduction, }; - pub const Reduction = struct { - enum : , + pub const Reduction = enum(u8) { + Mean, + Sum, }; // ═══════════════════════════════════════════════════════════ // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // sigmoid(x: f32) → f32 fn sigmoid(x: f32) -> f32 { - // Simple sigmoid approximation using rational function - if (x > 6.0) return 1.0; - if (x < -6.0) return 0.0; - - var abs_x = x; - if (abs_x < 0.0) abs_x = -abs_x; - - // Polynomial approximation for sigmoid - var p = 0.3178722 + abs_x * (0.3655024 + abs_x * (0.1811160 + abs_x * (0.0443368 + abs_x * 0.0086892))); - var p_inv = 1.0 / p; - - if (x > 0.0) { - return 1.0 - p_inv; - } else { - return p_inv; + if (x >= 0.0) { + return 1.0 / (1.0 + exp(-x)); } + const e = exp(x); + return e / (1.0 + e); } - // Helper function for log approximation - fn log_approx(x: f32) -> f32 { - // Simple log approximation for x in (0, 1] - if (x <= 0.0) return 10.0; // Large number for invalid input - if (x >= 1.0) return 0.0; - - // Polynomial approximation for log(x) around x=1 - var t = 1.0 - x; - if (t > 0.5) { - // For x < 0.5, use log(x) = -log(1/x) - return -log_approx(1.0 / x); + // p clipped into [eps, 1 - eps] so log stays finite + fn clip(p: f32, eps: f32) -> f32 { + if (p < eps) { + return eps; + } + if (p > 1.0 - eps) { + return 1.0 - eps; } - - // Taylor series: log(1-t) = -t - t^2/2 - t^3/3 - ... - var result = -t; - var t2 = t * t; - var t3 = t2 * t; - var t4 = t3 * t; - - result = result - t2 * 0.5 - t3 * 0.333333 - t4 * 0.25; - return result; + return p; } - // forward(predictions: []f32, targets: []f32, config: BinaryCEConfig) → f32 - fn forward(predictions: []f32, targets: []f32, config: BinaryCEConfig) -> f32 { - var loss: f32 = 0.0; - var i: f32 = 0.0; - while (i < predictions.size) { - var pred: f32 = predictions[f32(i)]; - var target: f32 = targets[f32(i)]; - i = i + 1.0; - - // Apply sigmoid if needed - if (config.from_logits) { - pred = sigmoid(pred); - } - - // Clip predictions to avoid numerical issues - pred = pred + config.epsilon; - if (pred > 1.0 - config.epsilon) { - pred = 1.0 - config.epsilon; - } - - // Simplified binary cross-entropy approximation - if (target > 0.5) { - // Target is 1, loss is -log(pred) - loss = loss + -log_approx(pred); - } else { - // Target is 0, loss is -log(1-pred) - loss = loss + -log_approx(1.0 - pred); - } + // -(t log p + (1 - t) log(1 - p)) for one element + fn element_loss(pred: f32, target: f32, config: BinaryCEConfig) -> f32 { + var p = pred; + if (config.from_logits) { + p = sigmoid(pred); } - - // Apply reduction (mean) - return loss / f32(predictions.size); + p = clip(p, config.epsilon); + return -(target * log(p) + (1.0 - target) * log(1.0 - p)); } - // forward_batch(predictions: [][]f32, targets: []f32, config: BinaryCEConfig) → f32 - fn forward_batch(predictions: [][]f32, targets: []f32, config: BinaryCEConfig) -> f32 { - var total_loss: f32 = 0.0; - var total_samples: f32 = 0.0; - - var batch_idx: f32 = 0.0; - while (batch_idx < predictions.size) { - var batch_preds = predictions[f32(batch_idx)]; - var i: f32 = 0.0; - while (i < batch_preds.size) { - var pred: f32 = batch_preds[f32(i)]; - var target: f32 = targets[f32(batch_idx) * batch_preds.size + f32(i)]; - i = i + 1.0; - - // Apply sigmoid if needed - if (config.from_logits) { - pred = sigmoid(pred); - } - - // Clip predictions to avoid numerical issues - pred = pred + config.epsilon; - if (pred > 1.0 - config.epsilon) { - pred = 1.0 - config.epsilon; - } - - // Simplified binary cross-entropy approximation - if (target > 0.5) { - // Target is 1, loss is -log(pred) - total_loss = total_loss + -log_approx(pred); - } else { - // Target is 0, loss is -log(1-pred) - total_loss = total_loss + -log_approx(1.0 - pred); - } - } - - total_samples = total_samples + f32(batch_preds.size); + // mean (or sum) of element_loss + fn forward(predictions: []const f32, targets: []const f32, config: BinaryCEConfig) -> f32 { + var loss : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + loss = loss + element_loss(predictions[i], targets[i], config); + i = i + 1; + } + if (config.reduction == Reduction.Sum) { + return loss; } - - // Apply reduction (mean across all samples) - return total_loss / total_samples; + return loss / @as(f32, @floatFromInt(predictions.len)); } - // gradient(predictions: []f32, targets: []f32, config: BinaryCEConfig) → []f32 - fn gradient(predictions: []f32, targets: []f32, config: BinaryCEConfig) -> []f32 { - var grads: []f32 = new f32[predictions.size]; - var i: f32 = 0.0; - while (i < predictions.size) { - var pred: f32 = predictions[f32(i)]; - var target: f32 = targets[f32(i)]; - i = i + 1.0; - var pred: f32 = predictions[i]; - var target: f32 = targets[i]; - - // Apply sigmoid if needed - if (config.from_logits) { - pred = sigmoid(pred); - } - - // Clip predictions to avoid division by zero - pred = pred + config.epsilon; - if (pred > 1.0 - config.epsilon) { - pred = 1.0 - config.epsilon; - } - - // Compute gradient + // A batch of rows of width `width`, flattened row-major: the mean over every element + fn forward_batch(predictions: []const f32, width: usize, targets: []const f32, config: BinaryCEConfig) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + total = total + element_loss(predictions[i], targets[i], config); + i = i + 1; + } + _ = width; + return total / @as(f32, @floatFromInt(predictions.len)); + } + + // Per-element gradient of the (unreduced) loss: + // from logits: sigmoid(z) - t + // from probabilities: -t / p + (1 - t) / (1 - p) + fn gradient(predictions: []const f32, targets: []const f32, config: BinaryCEConfig, grads: []f32) -> void { + var i : usize = 0; + while (i < predictions.len) { + const t = targets[i]; if (config.from_logits) { - // For logits, gradient is (pred - target) - grads[i] = pred - target; + grads[i] = sigmoid(predictions[i]) - t; } else { - // For probabilities, gradient is -(target/pred + (1-target)/(1-pred)) - var inv_pred = 1.0 / pred; - var inv_1_minus_pred = 1.0 / (1.0 - pred); - grads[i] = -(target * inv_pred + (1.0 - target) * inv_1_minus_pred); + const p = clip(predictions[i], config.epsilon); + grads[i] = -t / p + (1.0 - t) / (1.0 - p); } + i = i + 1; } - - return grads; + } + + fn cfg(from_logits: bool) -> BinaryCEConfig { + return BinaryCEConfig{ .from_logits = from_logits, .epsilon = DEFAULT_EPSILON, .reduction = Reduction.Mean }; + } + + // The fixture: predictions (a, b, c) against targets (1, 0, 1) + fn loss_of(a: f32, b: f32, c: f32, from_logits: bool) -> f32 { + const predictions : [3]f32 = [a, b, c]; + const targets : [3]f32 = [1.0, 0.0, 1.0]; + return forward(&predictions, &targets, cfg(from_logits)); + } + + fn grad_of(a: f32, b: f32, c: f32, from_logits: bool, index: usize) -> f32 { + const predictions : [3]f32 = [a, b, c]; + const targets : [3]f32 = [1.0, 0.0, 1.0]; + var grads : [3]f32 = [9.0] ** 3; + gradient(&predictions, &targets, cfg(from_logits), &grads); + return grads[index]; + } + + fn batch_loss() -> f32 { + const predictions : [4]f32 = [0.8, 0.3, 0.9, 0.1]; + const targets : [4]f32 = [1.0, 0.0, 1.0, 0.0]; + return forward_batch(&predictions, 2, &targets, cfg(false)); + } + + fn valid_input() -> f32 { + return loss_of(0.8, 0.3, 0.9, false); } // ═══════════════════════════════════════════════════════════ @@ -193,78 +145,70 @@ module BinaryCe; test sigmoid_basic_case given input = 0.0 when result = sigmoid(input) - then abs(result - 0.5) < 1e-6 + then @abs(result - 0.5) < 1e-6 test sigmoid_positive_input given input = 1.0 when result = sigmoid(input) - then result > 0.5 and result < 1.0 + then result > 0.5 and result < 1.0 and @abs(result - 0.7310586) < 0.000001 test sigmoid_negative_input given input = -1.0 when result = sigmoid(input) - then result > 0.0 and result < 0.5 + then result > 0.0 and result < 0.5 and @abs(result + sigmoid(1.0) - 1.0) < 0.000001 + // -(ln 0.8 + ln 0.7 + ln 0.9) / 3 = 0.2283930 test forward_basic_case - given predictions = [0.8, 0.3, 0.9] - given targets = [1.0, 0.0, 1.0] - given config = BinaryCEConfig{from_logits: false, epsilon: 1e-7, reduction: undefined} - when result = forward(predictions, targets, config) - then result > 0.0 + given result = loss_of(0.8, 0.3, 0.9, false) + then result > 0.0 and @abs(result - 0.2283930) < 0.000001 + // From logits (2, -1, 3) it is the same loss as from their sigmoids test forward_from_logits_case - given predictions = [2.0, -1.0, 3.0] - given targets = [1.0, 0.0, 1.0] - given config = BinaryCEConfig{from_logits: true, epsilon: 1e-7, reduction: undefined} - when result = forward(predictions, targets, config) - then result > 0.0 + given result = loss_of(2.0, -1.0, 3.0, true) + when probs = loss_of(sigmoid(2.0), sigmoid(-1.0), sigmoid(3.0), false) + then result > 0.0 and @abs(result - probs) < 0.000001 + // (-ln 0.8 - ln 0.7 - ln 0.9 - ln 0.9) / 4 = 0.1976349 test forward_batch_basic_case - given predictions = [[0.8, 0.3], [0.9, 0.1]] - given targets = [1.0, 0.0, 1.0, 0.0] - given config = BinaryCEConfig{from_logits: false, epsilon: 1e-7, reduction: undefined} - when result = forward_batch(predictions, targets, config) - then result > 0.0 + given result = batch_loss() + then result > 0.0 and @abs(result - 0.1976349) < 0.000001 + // t = 1 pulls p up (negative gradient), t = 0 pushes it down (positive) test gradient_basic_case - given predictions = [0.8, 0.3, 0.9] - given targets = [1.0, 0.0, 1.0] - given config = BinaryCEConfig{from_logits: false, epsilon: 1e-7, reduction: undefined} - when result = gradient(predictions, targets, config) - then result.length == 3 and result[0] < 0.0 and result[1] > 0.0 and result[2] < 0.0 + given g0 = grad_of(0.8, 0.3, 0.9, false, 0) + when g1 = grad_of(0.8, 0.3, 0.9, false, 1) + then g0 < 0.0 and g1 > 0.0 and grad_of(0.8, 0.3, 0.9, false, 2) < 0.0 and @abs(g0 + 1.25) < 0.000001 and @abs(g1 - 1.0 / 0.7) < 0.000001 + // From logits: sigmoid(z) - t, and it matches a finite difference of the loss test gradient_from_logits_case - given predictions = [2.0, -1.0, 3.0] - given targets = [1.0, 0.0, 1.0] - given config = BinaryCEConfig{from_logits: true, epsilon: 1e-7, reduction: undefined} - when result = gradient(predictions, targets, config) - then result.length == 3 + given g1 = grad_of(2.0, -1.0, 3.0, true, 1) + when slope = 3.0 * (loss_of(2.0, -1.0 + 0.001, 3.0, true) - loss_of(2.0, -1.0 - 0.001, 3.0, true)) / 0.002 + then @abs(g1 - sigmoid(-1.0)) < 0.000001 and @abs(g1 - slope) < 0.001 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // targets[i] in {0, 1}: a perfect prediction costs (almost) nothing invariant binary_ce_constraint_0 - given input = valid_input() - then true // targets[i] ∈ {0, 1} + assert loss_of(1.0, 0.0, 1.0, false) < 0.000001 + // 0 < epsilon << 1 invariant binary_ce_constraint_1 - given input = valid_input() - then true // 0 < epsilon << 1 + assert DEFAULT_EPSILON > 0.0 and DEFAULT_EPSILON < 0.001 + // name: binary_ce -- positive for an imperfect prediction invariant binary_ce_constraint_2 - given input = valid_input() - then true // name: binary_ce + assert valid_input() > 0.0 + // name: gradient -- zero where the logit already gives the target invariant binary_ce_constraint_3 - given input = valid_input() - then true // name: gradient + assert @abs(grad_of(30.0, -30.0, 30.0, true, 0)) < 0.000001 + // "Bishop (2006) - Pattern Recognition and Machine Learning": the loss falls as p nears t invariant binary_ce_constraint_4 - given input = valid_input() - then true // "Bishop (2006) - Pattern Recognition and Machine Learning" + assert loss_of(0.9, 0.1, 0.9, false) < loss_of(0.6, 0.4, 0.6, false) + // "Goodfellow et al. (2016) - Deep Learning": clipping keeps a certain wrong answer finite invariant binary_ce_constraint_5 - given input = valid_input() - then true // "Goodfellow et al. (2016) - Deep Learning" - + assert loss_of(0.0, 1.0, 0.0, false) < 20.0 diff --git a/apps/website/public/t27/files/specs/ml/optimizer/adam.t27 b/apps/website/public/t27/files/specs/ml/optimizer/adam.t27 index 1492ebd727..df8bd6334d 100644 --- a/apps/website/public/t27/files/specs/ml/optimizer/adam.t27 +++ b/apps/website/public/t27/files/specs/ml/optimizer/adam.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Adam adapts learning rate per parameter | φ² + 1/φ² = 3 | TRINITY +// #8980: step only checked its gradients with an undeclared `math::is_finite` +// and updated nothing; the tests asserted `result != undefined`. step is now +// Adam (Kingma and Ba, 2015) with bias correction. It refuses (returns false, +// changes nothing) when a gradient is NaN or infinite, which is what the old body +// validated. + module Adam; use base::types; use math::constants; @@ -30,57 +36,122 @@ module Adam; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // step(grads: []const f32) → void - fn step(grads: []const f32) -> void { - // Adam optimizer step implementation - // Update parameters using Adam algorithm: - // m_t = β1 * m_{t-1} + (1 - β1) * g_t - // v_t = β2 * v_{t-1} + (1 - β2) * g_t^2 - // m̂_t = m_t / (1 - β1^t) - // v̂_t = v_t / (1 - β2^t) - // θ_t = θ_{t-1} - learning_rate * m̂_t / (√v̂_t + ε) - - // For this basic implementation, we'll validate input gradients - // and demonstrate the Adam algorithm structure - if (grads.len == 0) { - return; // No gradients to process + // b^t for a whole t >= 0 + fn powi(b: f32, t: u32) -> f32 { + var r : f32 = 1.0; + var n : u32 = 0; + while (n < t) { + r = r * b; + n = n + 1; } - - // In a full implementation, this would: - // 1. Initialize first and second moment estimates if not already initialized - // 2. Update parameters with bias-corrected estimates - // 3. Apply weight decay if configured - // 4. Track step count for bias correction - - // For now, validate that gradients are reasonable values - var i: usize = 0; + return r; + } + + // NaN is the one value not equal to itself; inf - inf is NaN + fn is_finite(x: f32) -> bool { + return x == x and (x - x) == (x - x); + } + + // One Adam step number t (1-based) over params, with moment buffers m and v: + // g = grad + wd p + // m = b1 m + (1 - b1) g v = b2 v + (1 - b2) g^2 + // m_hat = m / (1 - b1^t) v_hat = v / (1 - b2^t) + // p = p - lr m_hat / (sqrt(v_hat) + eps) + fn step(params: []f32, grads: []const f32, m: []f32, v: []f32, t: u32, config: AdamConfig) -> bool { + var i : usize = 0; while (i < grads.len) { - // Ensure gradients are finite numbers - if (math::is_finite(grads[i]) == false) { - return; // Invalid gradient value + if (!is_finite(grads[i])) { + return false; } - i += 1; + i = i + 1; + } + const c1 = 1.0 - powi(config.beta1, t); + const c2 = 1.0 - powi(config.beta2, t); + i = 0; + while (i < params.len) { + const g = grads[i] + config.weight_decay * params[i]; + m[i] = config.beta1 * m[i] + (1.0 - config.beta1) * g; + v[i] = config.beta2 * v[i] + (1.0 - config.beta2) * g * g; + const m_hat = m[i] / c1; + const v_hat = v[i] / c2; + params[i] = params[i] - config.learning_rate * m_hat / (sqrt(v_hat) + config.epsilon); + i = i + 1; + } + return true; + } + + fn cfg(lr: f32) -> AdamConfig { + return AdamConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.0 }; + } + + // which: 0 = param, 1 = m, 2 = v after one step on params (1, 2, 3) with grads (g0, g1, g2) + fn first_step(g0: f32, g1: f32, g2: f32, which: u8, index: usize) -> f32 { + var params : [3]f32 = [1.0, 2.0, 3.0]; + const grads : [3]f32 = [g0, g1, g2]; + var m : [3]f32 = [0.0] ** 3; + var v : [3]f32 = [0.0] ** 3; + _ = step(¶ms, &grads, &m, &v, 1, cfg(0.001)); + if (which == 1) { + return m[index]; + } + if (which == 2) { + return v[index]; + } + return params[index]; + } + + // a / b at run time, where IEEE gives NaN for 0 / 0 and inf for 1 / 0 + fn ratio(a: f32, b: f32) -> f32 { + return a / b; + } + + fn accepts(g: f32) -> bool { + var params : [1]f32 = [1.0]; + const grads : [1]f32 = [g]; + var m : [1]f32 = [0.0]; + var v : [1]f32 = [0.0]; + return step(¶ms, &grads, &m, &v, 1, cfg(0.001)) and params[0] != 1.0; + } + + // Minimise (x - 3)^2 from 0 + fn descend(steps: u32) -> f32 { + var params : [1]f32 = [0.0]; + var m : [1]f32 = [0.0]; + var v : [1]f32 = [0.0]; + var t : u32 = 1; + while (t <= steps) { + const grads : [1]f32 = [2.0 * (params[0] - 3.0)]; + _ = step(¶ms, &grads, &m, &v, t, cfg(0.1)); + t = t + 1; } + return params[0]; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // Bias correction makes the first step lr * sign(g), whatever |g| is test step_basic_case - given input = default_input() - when result = step(input) - then result != undefined + given p0 = first_step(0.1, -5.0, 0.0, 0, 0) + when p1 = first_step(0.1, -5.0, 0.0, 0, 1) + then @abs(p0 - 0.999) < 0.000001 and @abs(p1 - 2.001) < 0.000001 and first_step(0.1, -5.0, 0.0, 0, 2) == 3.0 + // m = 0.1 g and v = 0.001 g^2 after the first step test step_with_gradients - given input = [0.1, 0.2, 0.3] - when result = step(input) - then result != undefined - // Verify function handles gradient input without crashing + given m2 = first_step(0.1, 0.2, 0.3, 1, 2) + when v2 = first_step(0.1, 0.2, 0.3, 2, 2) + then @abs(m2 - 0.03) < 0.0000001 and @abs(v2 - 0.00009) < 0.0000001 + // Finite gradients are applied; NaN and inf are refused test step_validates_gradients - given input = [1.5, -2.3, 0.0, 4.7] - when result = step(input) - then result != undefined - // Verify function processes valid gradients correctly + given ok = accepts(1.5) and accepts(-2.3) and accepts(4.7) + when refused = !accepts(ratio(0.0, 0.0)) and !accepts(ratio(1.0, 0.0)) + then ok and refused + + test step_descends_a_quadratic + given result = descend(500) + then @abs(result - 3.0) < 0.01 + invariant adam_betas_are_below_one + assert DEFAULT_BETA1 < 1.0 and DEFAULT_BETA2 < 1.0 and DEFAULT_BETA1 < DEFAULT_BETA2 and DEFAULT_EPSILON > 0.0 diff --git a/apps/website/public/t27/files/specs/ml/optimizer/lamb.t27 b/apps/website/public/t27/files/specs/ml/optimizer/lamb.t27 index 804fbc372d..5d9e8dfb42 100644 --- a/apps/website/public/t27/files/specs/ml/optimizer/lamb.t27 +++ b/apps/website/public/t27/files/specs/ml/optimizer/lamb.t27 @@ -2,9 +2,18 @@ // t27/specs/ // LAMB parameter update with trust ratio clipping | φ² + 1/φ² = 3 | TRINITY +// #8980: built with `append` on `[]` and `range` / `len` / `pow`, so it never +// compiled. The math was also not LAMB: v_hat used beta1's bias correction, the +// "trust ratio" was ||g|| / ||v_hat|| and was computed, then never applied to the +// step, and m and v were never written back. It is now You et al. (2020): +// r = m_hat / (sqrt(v_hat) + eps) + wd * w, trust = min(||w||, clip) / ||r||, +// w = w - lr * trust * r, +// per layer, over buffers the caller owns. + module Lamb; use base::types; use math::constants; + use ml::optimizer::adam; // ═══════════════════════════════════════════════════════════ // 1. Constants @@ -39,115 +48,138 @@ module Lamb; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // init_state(num_params: u32) → LAMBState - fn init_state(num_params: u32) -> LAMBState { - let m = []; - let v = []; - // Initialize moment arrays with zeros - for i in range(num_params) { - append(m, 0.0); - append(v, 0.0); + // m and v are the first num_params entries of the given buffers, zeroed; step 0 + fn init_state(m: []f32, v: []f32, num_params: u32) -> LAMBState { + var i : usize = 0; + while (i < num_params) { + m[i] = 0.0; + v[i] = 0.0; + i = i + 1; } - let step = 0u32; - return LAMBState { m: m, v: v, step: step }; + return LAMBState{ .m = m[0..num_params], .v = v[0..num_params], .step = 0 }; } - // compute_layer_update(params: []f32, grads: []f32, state: LAMBState, config: LAMBConfig) → []f32 - fn compute_layer_update(params: []f32, grads: []f32, state: LAMBState, config: LAMBConfig) -> []f32 { - let num_params = len(params); - let m = state.m; - let v = state.v; - let step = state.step; - - // Update biased first moment estimate - let m_next = []; - for i in range(num_params) { - let m_i = config.beta1 * m[i] + (1.0 - config.beta1) * grads[i]; - append(m_next, m_i); + // powi (b^t for a whole t) comes from specs/ml/optimizer/adam.t27 through `use` + + // Writes the moments for step (state.step + 1) into state.m / state.v and the update to + // ADD to params into `update`; returns update[0..n] + fn compute_layer_update(params: []const f32, grads: []const f32, state: LAMBState, config: LAMBConfig, update: []f32) -> []f32 { + const n = params.len; + const t = state.step + 1; + const c1 = 1.0 - powi(config.beta1, t); + const c2 = 1.0 - powi(config.beta2, t); + var w_norm : f32 = 0.0; + var r_norm : f32 = 0.0; + var i : usize = 0; + while (i < n) { + state.m[i] = config.beta1 * state.m[i] + (1.0 - config.beta1) * grads[i]; + state.v[i] = config.beta2 * state.v[i] + (1.0 - config.beta2) * grads[i] * grads[i]; + const r = (state.m[i] / c1) / (sqrt(state.v[i] / c2) + config.epsilon) + config.weight_decay * params[i]; + update[i] = r; + w_norm = w_norm + params[i] * params[i]; + r_norm = r_norm + r * r; + i = i + 1; } - - // Update biased second raw moment estimate - let v_next = []; - for i in range(num_params) { - let v_i = config.beta2 * v[i] + (1.0 - config.beta2) * grads[i] * grads[i]; - append(v_next, v_i); + w_norm = sqrt(w_norm); + r_norm = sqrt(r_norm); + var trust : f32 = 1.0; + if (w_norm > 0.0 and r_norm > 0.0) { + trust = @min(w_norm, config.clip_threshold) / r_norm; } - - // Compute bias-corrected first and second moment estimates - let m_hat = []; - let v_hat = []; - let correction = 1.0 - pow(config.beta1, f32(step + 1)); - for i in range(num_params) { - append(m_hat, m_next[i] / correction); - append(v_hat, v_next[i] / correction); + i = 0; + while (i < n) { + update[i] = -config.learning_rate * trust * update[i]; + i = i + 1; } - - // Compute trust ratio for adaptive clipping - let trust_ratio = 0.0; - let v_hat_sum = 0.0; - let grad_norm = 0.0; - for i in range(num_params) { - v_hat_sum += v_hat[i]; - grad_norm += grads[i] * grads[i]; + return update[0..n]; + } + + // One LAMB step over several layers packed back to back in `params` (layer k has + // sizes[k] entries), each with its own state; params change in place, each step + 1. + fn forward(params: []f32, grads: []const f32, sizes: []const usize, states: []LAMBState, config: LAMBConfig, scratch: []f32) -> void { + var start : usize = 0; + var k : usize = 0; + while (k < sizes.len) { + const end = start + sizes[k]; + const upd = compute_layer_update(params[start..end], grads[start..end], states[k], config, scratch); + var j : usize = 0; + while (j < sizes[k]) { + params[start + j] = params[start + j] + upd[j]; + j = j + 1; + } + states[k].step = states[k].step + 1; + start = end; + k = k + 1; } - let v_hat_norm = sqrt(v_hat_sum); - let grad_norm_val = sqrt(grad_norm); - if v_hat_norm > 0.0 and grad_norm_val > 0.0 { - trust_ratio = grad_norm_val / v_hat_norm; + } + + fn cfg(lr: f32) -> LAMBConfig { + return LAMBConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.01, .clip_threshold = DEFAULT_CLIP_THRESHOLD }; + } + + // which: 0 = m.len, 1 = v.len, 2 = step, 3 = m[0], 4 = v[99] + fn init_probe(which: u8) -> f32 { + var m : [100]f32 = [9.0] ** 100; + var v : [100]f32 = [9.0] ** 100; + const st = init_state(&m, &v, 100); + if (which == 0) { + return @as(f32, @floatFromInt(st.m.len)); } - - // Apply adaptive clipping - let clipped_grads = []; - for i in range(num_params) { - let clipped_grad = grads[i]; - if trust_ratio > config.clip_threshold { - clipped_grad = clipped_grad * (config.clip_threshold / trust_ratio); - } - append(clipped_grads, clipped_grad); + if (which == 1) { + return @as(f32, @floatFromInt(st.v.len)); } - - // Apply weight decay and compute update - let update = []; - for i in range(num_params) { - let update_i = (-config.learning_rate) * (m_hat[i] / (sqrt(v_hat[i]) + config.epsilon) + config.weight_decay * params[i]); - append(update, update_i); + if (which == 2) { + return @as(f32, @floatFromInt(st.step)); } - - return update; + if (which == 3) { + return st.m[0]; + } + return st.v[99]; } - // forward(layers: [][]f32, grads: [][]f32, states: []LAMBState, config: LAMBConfig) → [][]f32 - fn forward(layers: [][]f32, grads: [][]f32, states: []LAMBState, config: LAMBConfig) -> [][]f32 { - let num_layers = len(layers); - let updated_layers = []; - - for i in range(num_layers) { - let layer = layers[i]; - let layer_grads = grads[i]; - let state = states[i]; - - // Compute layer updates using LAMB algorithm - let updates = compute_layer_update(layer, layer_grads, state, config); - - // Apply updates to get updated layer - let updated_layer = []; - for j in range(len(layer)) { - let updated_param = layer[j] + updates[j]; - append(updated_layer, updated_param); - } - - // Update state for next iteration - let updated_state = LAMBState { - m: state.m, // These should be updated in compute_layer_update, but for now keep as is - v: state.v, - step: state.step + 1u32, - }; - - // Store updated state (in a real implementation, we'd update the states array) - append(updated_layers, updated_layer); + // update[index] of the first step on params (1, 2, 3), grads (0.1, 0.2, 0.3); index 3 = its length + fn first_update(index: usize) -> f32 { + const params : [3]f32 = [1.0, 2.0, 3.0]; + const grads : [3]f32 = [0.1, 0.2, 0.3]; + var m : [3]f32 = undefined; + var v : [3]f32 = undefined; + var update : [3]f32 = [9.0] ** 3; + const u = compute_layer_update(¶ms, &grads, init_state(&m, &v, 3), cfg(0.001), &update); + if (index == 3) { + return @as(f32, @floatFromInt(u.len)); } - - return updated_layers; + return u[index]; + } + + // The layer-wise property: scaling a layer's weights by 10 scales its step by 10 + fn step_norm(scale: f32) -> f32 { + const params : [2]f32 = [1.0 * scale, 2.0 * scale]; + const grads : [2]f32 = [0.1, 0.2]; + var m : [2]f32 = undefined; + var v : [2]f32 = undefined; + var update : [2]f32 = undefined; + const u = compute_layer_update(¶ms, &grads, init_state(&m, &v, 2), cfg(0.001), &update); + return sqrt(u[0] * u[0] + u[1] * u[1]); + } + + // Two layers (1, 2) and (3, 4), one step; which: 0..3 = new params, 4 = step of layer 1 + fn two_layers(which: usize) -> f32 { + var params : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + const grads : [4]f32 = [0.1, 0.2, 0.3, 0.4]; + const sizes : [2]usize = [2, 2]; + var m : [4]f32 = undefined; + var v : [4]f32 = undefined; + var states : [2]LAMBState = [init_state(m[0..2], v[0..2], 2), init_state(m[2..4], v[2..4], 2)]; + var scratch : [2]f32 = undefined; + forward(¶ms, &grads, &sizes, &states, cfg(0.001), &scratch); + if (which == 4) { + return @as(f32, @floatFromInt(states[1].step)); + } + return params[which]; + } + + fn valid_input() -> f32 { + return DEFAULT_BETA1; } // ═══════════════════════════════════════════════════════════ @@ -155,89 +187,60 @@ module Lamb; // ═══════════════════════════════════════════════════════════ test init_state_basic_case - given num_params = 100u32 - when result = init_state(num_params) - then len(result.m) == num_params - and len(result.v) == num_params - and result.step == 0u32 - and result.m[0] == 0.0 - and result.v[0] == 0.0 + given num_params = 100.0 + when m_len = init_probe(0) + then m_len == num_params and init_probe(1) == num_params and init_probe(2) == 0.0 and init_probe(3) == 0.0 and init_probe(4) == 0.0 + // Every update is negative (descent) and the step's norm is lr * min(||w||, 10) = 0.001 ||w|| test compute_layer_update_basic_case - given params = [1.0, 2.0, 3.0] - given grads = [0.1, 0.2, 0.3] - given state = init_state(3u32) - given config = LAMBConfig { - learning_rate: 0.001, - beta1: 0.9, - beta2: 0.999, - epsilon: 1e-6, - weight_decay: 0.01, - clip_threshold: 10.0 - } - when result = compute_layer_update(params, grads, state, config) - then len(result) == len(params) - and result[0] != params[0] // Update should change the parameter - and result[1] != params[1] - and result[2] != params[2] - and result[0] < 0.0 // Updates should be negative (gradient descent) - and result[1] < 0.0 - and result[2] < 0.0 + given u0 = first_update(0) + when n = first_update(3) + then n == 3.0 and u0 < 0.0 and first_update(1) < 0.0 and first_update(2) < 0.0 and @abs(sqrt(u0 * u0 + first_update(1) * first_update(1) + first_update(2) * first_update(2)) - 0.001 * sqrt(@as(f32, 14.0))) < 0.0000001 + // Each layer moves, and each layer's state advances test forward_basic_case - given layers = [[1.0, 2.0], [3.0, 4.0]] - given grads = [[0.1, 0.2], [0.3, 0.4]] - given states = [init_state(2u32), init_state(2u32)] - given config = LAMBConfig { - learning_rate: 0.001, - beta1: 0.9, - beta2: 0.999, - epsilon: 1e-6, - weight_decay: 0.01, - clip_threshold: 10.0 - } - when result = forward(layers, grads, states, config) - then len(result) == len(layers) - and len(result[0]) == len(layers[0]) - and len(result[1]) == len(layers[1]) - and result[0][0] != layers[0][0] // First layer should be updated - and result[0][1] != layers[0][1] - and result[1][0] != layers[1][0] // Second layer should be updated - and result[1][1] != layers[1][1] + given p0 = two_layers(0) + when p3 = two_layers(3) + then p0 != 1.0 and two_layers(1) != 2.0 and two_layers(2) != 3.0 and p3 != 4.0 and p0 < 1.0 and two_layers(4) == 1.0 + + // LAMB's point: the step is proportional to the layer's weight norm (up to the clip) + test compute_layer_update_scales_with_the_layer + given small = step_norm(1.0) + when large = step_norm(3.0) + then @abs(large / small - 3.0) < 0.001 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // 0 < beta1 < 1 invariant lamb_constraint_0 - given input = valid_input() - then true // 0 < beta1 < 1 + assert valid_input() > 0.0 and valid_input() < 1.0 + // 0 < beta2 < 1 invariant lamb_constraint_1 - given input = valid_input() - then true // 0 < beta2 < 1 + assert DEFAULT_BETA2 > 0.0 and DEFAULT_BETA2 < 1.0 + // epsilon > 0 invariant lamb_constraint_2 - given input = valid_input() - then true // epsilon > 0 + assert DEFAULT_EPSILON > 0.0 + // clip_threshold > 0 invariant lamb_constraint_3 - given input = valid_input() - then true // clip_threshold > 0 + assert DEFAULT_CLIP_THRESHOLD > 0.0 + // name: trust_ratio -- capped by clip_threshold: a layer of norm 50 steps as one of norm 10 invariant lamb_constraint_4 - given input = valid_input() - then true // name: trust_ratio + assert DEFAULT_CLIP_THRESHOLD == 10.0 + // name: lamb_update -- bias correction makes the first m_hat equal g invariant lamb_constraint_5 - given input = valid_input() - then true // name: lamb_update + assert powi(DEFAULT_BETA1, 1) == DEFAULT_BETA1 and DEFAULT_LR > 0.0 + // "You et al. (2020) - Large Batch Optimization for Deep Learning: Training BERT in 76 minutes" invariant lamb_constraint_6 - given input = valid_input() - then true // "You et al. (2020) - Large Batch Optimization for Deep Learning: Training BERT in 76 minutes" + assert powi(0.5, 3) == 0.125 + // "Used in BERT, T5, and other large-scale Transformer training" invariant lamb_constraint_7 - given input = valid_input() - then true // "Used in BERT, T5, and other large-scale Transformer training" - + assert DEFAULT_BETA2 > DEFAULT_BETA1 diff --git a/apps/website/public/t27/files/specs/ml/optimizer/sgd.t27 b/apps/website/public/t27/files/specs/ml/optimizer/sgd.t27 index c2616d1101..af7c998fa1 100644 --- a/apps/website/public/t27/files/specs/ml/optimizer/sgd.t27 +++ b/apps/website/public/t27/files/specs/ml/optimizer/sgd.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Nesterov accelerated gradient (NAG) | φ² + 1/φ² = 3 | TRINITY +// #8980: init called `new f32[n]`; update read undeclared locals; dampening and +// nesterov were ignored; and weight decay was ADDED to the parameter +// (`- v + wd * p`), which grows the weights it should shrink. update is now +// PyTorch's SGD: g = grad + wd p; v = mu v + (1 - dampening) g; +// step = g + mu v (Nesterov) or v; p = p - lr step. + module Sgd; use base::types; use math::constants; @@ -33,74 +39,126 @@ module Sgd; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // init(state: SGDState, param_count: u32) → void + // init: the first param_count velocities start at zero (the caller owns the buffer) fn init(state: SGDState, param_count: u32) -> void { - // Initialize velocity array with zeros - state.velocity = new f32[param_count]; + var i : usize = 0; + while (i < param_count) { + state.velocity[i] = 0.0; + i = i + 1; + } } - // update(params: []f32, grads: []const f32, state: SGDState, config: SGDConfig) -> void fn update(params: []f32, grads: []const f32, state: SGDState, config: SGDConfig) -> void { - // Nesterov accelerated gradient descent update - i = 0; - while (i < params.size()) { - velocity = state.velocity[i]; - grad = grads[i]; - - // Classic momentum update with Nesterov acceleration - velocity_new = config.momentum * velocity + config.learning_rate * grad; - state.velocity[i] = velocity_new; - - // Update parameter with velocity and weight decay - params[i] = params[i] - velocity_new + config.weight_decay * params[i]; + var i : usize = 0; + while (i < params.len) { + const g = grads[i] + config.weight_decay * params[i]; + var step = g; + if (config.momentum > 0.0) { + state.velocity[i] = config.momentum * state.velocity[i] + (1.0 - config.dampening) * g; + if (config.nesterov) { + step = g + config.momentum * state.velocity[i]; + } else { + step = state.velocity[i]; + } + } + params[i] = params[i] - config.learning_rate * step; i = i + 1; } } + fn cfg(lr: f32, momentum: f32, wd: f32, nesterov: bool) -> SGDConfig { + return SGDConfig{ .learning_rate = lr, .momentum = momentum, .weight_decay = wd, .dampening = 0.0, .nesterov = nesterov }; + } + + // Minimise f(x) = (x - 3)^2 (gradient 2 (x - 3)) from x = 0 for `steps` steps + fn descend(lr: f32, momentum: f32, nesterov: bool, steps: u32) -> f32 { + var params : [1]f32 = [0.0]; + var velocity : [1]f32 = [5.0]; + const state = SGDState{ .velocity = &velocity }; + init(state, 1); + var n : u32 = 0; + while (n < steps) { + const grads : [1]f32 = [2.0 * (params[0] - 3.0)]; + update(¶ms, &grads, state, cfg(lr, momentum, 0.0, nesterov)); + n = n + 1; + } + return params[0]; + } + + fn init_zeroes(index: usize) -> f32 { + var velocity : [3]f32 = [7.0, 7.0, 7.0]; + init(SGDState{ .velocity = &velocity }, 3); + return velocity[index]; + } + + // One step on params (1, 2), grads (0.1, 0.2), momentum 0.9, weight decay 0.001 + fn one_step(index: usize) -> f32 { + var params : [2]f32 = [1.0, 2.0]; + const grads : [2]f32 = [0.1, 0.2]; + var velocity : [2]f32 = [0.0, 0.0]; + update(¶ms, &grads, SGDState{ .velocity = &velocity }, cfg(0.01, 0.9, 0.001, false)); + return params[index]; + } + + // A step with zero gradient and weight decay shrinks the weight toward 0 + fn decay_step() -> f32 { + var params : [1]f32 = [2.0]; + const grads : [1]f32 = [0.0]; + var velocity : [1]f32 = [0.0]; + update(¶ms, &grads, SGDState{ .velocity = &velocity }, cfg(0.1, 0.0, 0.5, false)); + return params[0]; + } + + fn valid_input() -> f32 { + return DEFAULT_LR; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ - test "init_basic_case" { - // init takes the state by value, so the velocity it allocates is not observable - // here; this runs it on a fresh state rather than asserting what it cannot show. - var empty: [0]f32 = []; - var state = SGDState{ .velocity = &empty }; - init(state, 3); - } + test "init_basic_case" + given first = init_zeroes(0) + when last = init_zeroes(2) + then first == 0.0 and last == 0.0 - test "update_basic_case" { - var params: [2]f32 = [1.0, 2.0]; - var grads: [2]f32 = [0.1, 0.2]; - var velocity: [2]f32 = [0.0, 0.0]; - var state = SGDState{ .velocity = &velocity }; - var config = SGDConfig{ .learning_rate = 0.01, .momentum = 0.9, .weight_decay = 0.001, .dampening = 0.0, .nesterov = false }; - update(¶ms, &grads, state, config); - assert(params[0] != 1.0); // updated - assert(params[1] != 2.0); // updated - } + // v = g + wd p (momentum starts at 0): p0 = 1 - 0.01 (0.1 + 0.001) = 0.99899 + test "update_basic_case" + given p0 = one_step(0) + when p1 = one_step(1) + then p0 != 1.0 and p1 != 2.0 and @abs(p0 - 0.99899) < 0.000001 and @abs(p1 - (2.0 - 0.01 * 0.202)) < 0.000001 + + // Weight decay pulls the weight toward 0: 2 - 0.1 * 0.5 * 2 = 1.9 + test "update_weight_decay_shrinks" + given result = decay_step() + then @abs(result - 1.9) < 0.000001 + + // Plain, momentum and Nesterov SGD all reach the minimum at 3 + test "update_descends_a_quadratic" + given plain = descend(0.1, 0.0, false, 100) + when heavy = descend(0.05, 0.9, false, 300) + then @abs(plain - 3.0) < 0.0001 and @abs(heavy - 3.0) < 0.0001 and @abs(descend(0.05, 0.9, true, 300) - 3.0) < 0.0001 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // learning_rate > 0 invariant sgd_constraint_0 - given input = valid_input() - then true // learning_rate > 0 + assert valid_input() > 0.0 + // 0 <= momentum < 1 invariant sgd_constraint_1 - given input = valid_input() - then true // 0 <= momentum < 1 + assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0 + // weight_decay >= 0: a non-negative decay never grows a weight with zero gradient invariant sgd_constraint_2 - given input = valid_input() - then true // weight_decay >= 0 + assert decay_step() < 2.0 + // params.size() == grads.size(): every parameter moves invariant sgd_constraint_3 - given input = valid_input() - then true // params.size() == grads.size() + assert one_step(0) != 1.0 and one_step(1) != 2.0 + // If momentum > 0: state.velocity.size() == params.size() -- init zeroes all of it invariant sgd_constraint_4 - given input = valid_input() - then true // If momentum > 0: state.velocity.size() == params.size() - + assert init_zeroes(1) == 0.0 diff --git a/apps/website/public/t27/files/specs/ml/pathway/mlp.t27 b/apps/website/public/t27/files/specs/ml/pathway/mlp.t27 index 787801ba76..df03c810ed 100644 --- a/apps/website/public/t27/files/specs/ml/pathway/mlp.t27 +++ b/apps/website/public/t27/files/specs/ml/pathway/mlp.t27 @@ -2,6 +2,13 @@ // t27/specs/ // ReLU activation for hidden layers | φ² + 1/φ² = 3 | TRINITY +// #8980: forward computed the hidden layer and wrote it into `output` (the +// second layer never ran); init called an undeclared `alloc_f32`; the tests +// called undeclared `create_test_*` helpers; and the invariants asserted `true`. +// The MLP is now two layers, h = relu(W1 x + b1) and y = W2 h + b2, over buffers +// the caller owns. train_step adds backpropagation with an SGD update, and the +// tests train the network on XOR, which no single linear layer can fit. + module Mlp; use base::types; use math::constants; @@ -35,129 +42,283 @@ module Mlp; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32, state: MLPState, output: []f32, config: MLPConfig) → void - fn forward(input: []const f32, state: MLPState, output: []f32, config: MLPConfig) -> void { - // Forward pass implementation for MLP - // ReLU activation for hidden layers - // Process input through the network layers - - // First layer: input to hidden with ReLU activation - var i : usize = 0; - while (i < config.hidden_size) : (i += 1) { - var sum : f32 = 0.0; - var j : usize = 0; - while (j < config.input_size) : (j += 1) { - sum += input[j] * state.w1[i * config.input_size + j]; + // One dense layer: out[o] = sum_i w[o * n_in + i] in[i] + b[o], relu when asked + fn layer(input: []const f32, w: []const f32, b: []const f32, n_in: u32, n_out: u32, relu: bool, out: []f32) -> void { + var o : usize = 0; + while (o < n_out) { + var sum : f32 = b[o]; + var i : usize = 0; + while (i < n_in) { + sum = sum + w[o * n_in + i] * input[i]; + i = i + 1; } - sum += state.b1[i]; - // ReLU activation - if (sum > 0.0) { - output[i] = sum; - } else { - output[i] = 0.0; + if (relu and sum < 0.0) { + sum = 0.0; } + out[o] = sum; + o = o + 1; + } + } + + // h = relu(W1 x + b1) into `hidden`, y = W2 h + b2 into `output` + fn forward(input: []const f32, state: MLPState, hidden: []f32, output: []f32, config: MLPConfig) -> void { + layer(input, state.w1, state.b1, config.input_size, config.hidden_size, true, hidden); + layer(hidden, state.w2, state.b2, config.hidden_size, config.output_size, false, output); + } + + // He-scaled deterministic init: w in [-1, 1) sqrt(2 / fan_in) from a fixed hash of the + // index (salt tells the layers apart); every bias 0 + fn init_weights(w: []f32, fan_in: u32, salt: usize) -> void { + const scale : f32 = sqrt(2.0 / @as(f32, @floatFromInt(fan_in))); + var k : usize = 0; + while (k < w.len) { + const h : u32 = @as(u32, @intCast(((k + salt) * 2654435761) % 1000)); + w[k] = (@as(f32, @floatFromInt(h)) / 500.0 - 1.0) * scale; + k = k + 1; + } + } + + fn zero(v: []f32) -> void { + var k : usize = 0; + while (k < v.len) { + v[k] = 0.0; + k = k + 1; } } - // init(state: MLPState, config: MLPConfig) → void fn init(state: MLPState, config: MLPConfig) -> void { - // Initialize MLP state with default values - // Allocate weight and bias matrices with proper dimensions - state.w1 = alloc_f32(config.input_size * config.hidden_size); - state.b1 = alloc_f32(config.hidden_size); - state.w2 = alloc_f32(config.hidden_size * config.output_size); - state.b2 = alloc_f32(config.output_size); - - // Initialize weights with small random values + init_weights(state.w1, config.input_size, 1); + zero(state.b1); + init_weights(state.w2, config.hidden_size, 7); + zero(state.b2); + } + + // One SGD step on the loss 0.5 * sum_o (y_o - t_o)^2; returns the loss before the step. + // d2_o = y_o - t_o (output error) + // d1_i = [z_i > 0] sum_o W2[o][i] d2_o (backpropagated through relu) + // W2 -= lr d2 h^T, b2 -= lr d2; W1 -= lr d1 x^T, b1 -= lr d1 + fn train_step(input: []const f32, target: []const f32, state: MLPState, hidden: []f32, delta: []f32, output: []f32, lr: f32, config: MLPConfig) -> f32 { + forward(input, state, hidden, output, config); + var loss : f32 = 0.0; + var o : usize = 0; + while (o < config.output_size) { + const e = output[o] - target[o]; + loss = loss + 0.5 * e * e; + o = o + 1; + } var i : usize = 0; - while (i < config.input_size * config.hidden_size) : (i += 1) { - state.w1[i] = 0.01; // Small fixed values for now + while (i < config.hidden_size) { + var back : f32 = 0.0; + if (hidden[i] > 0.0) { + o = 0; + while (o < config.output_size) { + back = back + state.w2[o * config.hidden_size + i] * (output[o] - target[o]); + o = o + 1; + } + } + delta[i] = back; + i = i + 1; } - - // Initialize biases to zero - i = 0; - while (i < config.hidden_size) : (i += 1) { - state.b1[i] = 0.0; + o = 0; + while (o < config.output_size) { + const d2 = output[o] - target[o]; + i = 0; + while (i < config.hidden_size) { + state.w2[o * config.hidden_size + i] = state.w2[o * config.hidden_size + i] - lr * d2 * hidden[i]; + i = i + 1; + } + state.b2[o] = state.b2[o] - lr * d2; + o = o + 1; } - - // Initialize second layer weights with small random values i = 0; - while (i < config.hidden_size * config.output_size) : (i += 1) { - state.w2[i] = 0.01; // Small fixed values for now + while (i < config.hidden_size) { + var j : usize = 0; + while (j < config.input_size) { + state.w1[i * config.input_size + j] = state.w1[i * config.input_size + j] - lr * delta[i] * input[j]; + j = j + 1; + } + state.b1[i] = state.b1[i] - lr * delta[i]; + i = i + 1; } - - // Initialize second layer biases to zero - i = 0; - while (i < config.output_size) : (i += 1) { - state.b2[i] = 0.0; + return loss; + } + + fn mnist() -> MLPConfig { + return MLPConfig{ .input_size = MNIST_INPUT_SIZE, .hidden_size = DEFAULT_HIDDEN_SIZE, .output_size = MNIST_OUTPUT_SIZE }; + } + + // which: 0 = output[index], 1 = min over every output, 2 = number of outputs written, + // on the MNIST shape with input pixel k = (k % 7) / 7 + fn mnist_forward(which: u8, index: usize) -> f32 { + var w1 : [784 * 128]f32 = undefined; + var b1 : [128]f32 = undefined; + var w2 : [128 * 10]f32 = undefined; + var b2 : [10]f32 = undefined; + const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }; + init(state, mnist()); + var input : [784]f32 = undefined; + var k : usize = 0; + while (k < 784) { + input[k] = @as(f32, @floatFromInt(k % 7)) / 7.0; + k = k + 1; + } + var hidden : [128]f32 = undefined; + var output : [11]f32 = [-99.0] ** 11; + forward(&input, state, &hidden, &output, mnist()); + if (which == 0) { + return output[index]; + } + var min_h : f32 = hidden[0]; + var written : f32 = 0.0; + k = 0; + while (k < 128) { + min_h = @min(min_h, hidden[k]); + k = k + 1; + } + k = 0; + while (k < 11) { + if (output[k] != -99.0) { + written = written + 1.0; + } + k = k + 1; + } + if (which == 1) { + return min_h; + } + return written; + } + + // which: 0 = w1.len written by init, 1 = b1[0], 2 = b2[0], 3 = largest |w1| + fn mnist_init(which: u8) -> f32 { + var w1 : [784 * 128]f32 = [9.0] ** (784 * 128); + var b1 : [128]f32 = [9.0] ** 128; + var w2 : [128 * 10]f32 = [9.0] ** (128 * 10); + var b2 : [10]f32 = [9.0] ** 10; + init(MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, mnist()); + var written : f32 = 0.0; + var largest : f32 = 0.0; + var k : usize = 0; + while (k < w1.len) { + if (w1[k] != 9.0) { + written = written + 1.0; + } + largest = @max(largest, @abs(w1[k])); + k = k + 1; + } + if (which == 0) { + return written; } + if (which == 1) { + return b1[0]; + } + if (which == 2) { + return b2[0]; + } + return largest; + } + + // Train a 2-8-1 network on XOR for `epochs` passes over the four cases. + // which: 0 = total loss of the first epoch, 1 = total loss of the last epoch, + // 2 + c = the trained network's output for case c + fn xor(epochs: u32, which: usize) -> f32 { + const cfg = MLPConfig{ .input_size = 2, .hidden_size = 8, .output_size = 1 }; + var w1 : [16]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [8]f32 = undefined; + var b2 : [1]f32 = undefined; + const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }; + init(state, cfg); + const xs : [8]f32 = [0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]; + const ts : [4]f32 = [0.0, 1.0, 1.0, 0.0]; + var hidden : [8]f32 = undefined; + var delta : [8]f32 = undefined; + var output : [1]f32 = undefined; + var first : f32 = 0.0; + var last : f32 = 0.0; + var e : u32 = 0; + while (e < epochs) { + var total : f32 = 0.0; + var c : usize = 0; + while (c < 4) { + total = total + train_step(xs[c * 2 .. c * 2 + 2], ts[c .. c + 1], state, &hidden, &delta, &output, 0.05, cfg); + c = c + 1; + } + if (e == 0) { + first = total; + } + last = total; + e = e + 1; + } + if (which == 0) { + return first; + } + if (which == 1) { + return last; + } + forward(xs[(which - 2) * 2 .. (which - 2) * 2 + 2], state, &hidden, &output, cfg); + return output[0]; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // 784 -> 128 -> 10: exactly the 10 outputs are written, the 11th slot is untouched test forward_output_size - given input = create_test_input(MNIST_INPUT_SIZE) - when output = create_test_output(MNIST_OUTPUT_SIZE) - and state = create_test_state(MNIST_INPUT_SIZE, DEFAULT_HIDDEN_SIZE, MNIST_OUTPUT_SIZE) - and config = MLPConfig { input_size: MNIST_INPUT_SIZE, hidden_size: DEFAULT_HIDDEN_SIZE, output_size: MNIST_OUTPUT_SIZE } - when forward(input, state, output, config) - then output.size() == MNIST_OUTPUT_SIZE + given written = mnist_forward(2, 0) + when spare = mnist_forward(0, 10) + then written == 10.0 and spare == -99.0 + // The hidden layer is relu, so no hidden unit is negative test forward_relu_activation - given input = create_test_input(MNIST_INPUT_SIZE) - when output = create_test_output(MNIST_OUTPUT_SIZE) - and state = create_test_state(MNIST_INPUT_SIZE, DEFAULT_HIDDEN_SIZE, MNIST_OUTPUT_SIZE) - and config = MLPConfig { input_size: MNIST_INPUT_SIZE, hidden_size: DEFAULT_HIDDEN_SIZE, output_size: MNIST_OUTPUT_SIZE } - when forward(input, state, output, config) - then output[0] >= 0.0 // ReLU activation should produce non-negative values + given min_hidden = mnist_forward(1, 0) + then min_hidden >= 0.0 + // init writes every one of the 784 * 128 first-layer weights, each within sqrt(2 / 784) = 0.05051 test init_allocation_sizes - given state = MLPState { w1: [], b1: [], w2: [], b2: [] } - and config = MLPConfig { input_size: MNIST_INPUT_SIZE, hidden_size: DEFAULT_HIDDEN_SIZE, output_size: MNIST_OUTPUT_SIZE } - when init(state, config) - then state.w1.size() == MNIST_INPUT_SIZE * DEFAULT_HIDDEN_SIZE - and state.b1.size() == DEFAULT_HIDDEN_SIZE - and state.w2.size() == DEFAULT_HIDDEN_SIZE * MNIST_OUTPUT_SIZE - and state.b2.size() == MNIST_OUTPUT_SIZE + given written = mnist_init(0) + when largest = mnist_init(3) + then written == 100352.0 and largest <= 0.0506 and largest > 0.0 test init_bias_initialization - given state = MLPState { w1: [], b1: [], w2: [], b2: [] } - and config = MLPConfig { input_size: MNIST_INPUT_SIZE, hidden_size: DEFAULT_HIDDEN_SIZE, output_size: MNIST_OUTPUT_SIZE } - when init(state, config) - then state.b1[0] == 0.0 // Biases should be initialized to zero - and state.b2[0] == 0.0 // Biases should be initialized to zero + given b1 = mnist_init(1) + when b2 = mnist_init(2) + then b1 == 0.0 and b2 == 0.0 + + // Backpropagation learns XOR: the loss falls by more than 100x, and each output is within 0.1 + test train_step_learns_xor + given first = xor(2000, 0) + when last = xor(2000, 1) + then last < first / 100.0 and @abs(xor(2000, 2)) < 0.1 and @abs(xor(2000, 3) - 1.0) < 0.1 and @abs(xor(2000, 4) - 1.0) < 0.1 and @abs(xor(2000, 5)) < 0.1 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // input_size == MNIST_INPUT_SIZE (784) invariant mlp_constraint_0 - given input = valid_input() - then true // input_size == MNIST_INPUT_SIZE (784) + assert mnist().input_size == 784 + // output_size == MNIST_OUTPUT_SIZE (10) invariant mlp_constraint_1 - given input = valid_input() - then true // output_size == MNIST_OUTPUT_SIZE (10) + assert mnist().output_size == 10 + // hidden_size > 0 invariant mlp_constraint_2 - given input = valid_input() - then true // hidden_size > 0 + assert mnist().hidden_size > 0 + // w1.size() == input_size * hidden_size invariant mlp_constraint_3 - given input = valid_input() - then true // w1.size() == input_size * hidden_size + assert mnist().input_size * mnist().hidden_size == 100352 + // w2.size() == hidden_size * output_size invariant mlp_constraint_4 - given input = valid_input() - then true // w2.size() == hidden_size * output_size + assert mnist().hidden_size * mnist().output_size == 1280 + // b1.size() == hidden_size invariant mlp_constraint_5 - given input = valid_input() - then true // b1.size() == hidden_size + assert DEFAULT_HIDDEN_SIZE == 128 + // b2.size() == output_size invariant mlp_constraint_6 - given input = valid_input() - then true // b2.size() == output_size - + assert MNIST_OUTPUT_SIZE == 10 diff --git a/apps/website/public/t27/files/specs/ml/recurrent/attention_mechanism.t27 b/apps/website/public/t27/files/specs/ml/recurrent/attention_mechanism.t27 index 393f399ddb..48dce23e6c 100644 --- a/apps/website/public/t27/files/specs/ml/recurrent/attention_mechanism.t27 +++ b/apps/website/public/t27/files/specs/ml/recurrent/attention_mechanism.t27 @@ -2,6 +2,15 @@ // t27/specs/ // Memory-efficient attention for long sequences | φ² + 1/φ² = 3 | TRINITY +// #8980: redeclared `var i` in one scope four times, called `@infinity()` and +// `@random()` (not Zig), and indexed every row as head_dim wide inside d_model-wide +// rows. backward also skipped the softmax Jacobian: it pushed dL/dweights straight +// into the scores. It is now multi-head scaled dot-product attention over seq x +// d_model rows. Head h reads columns h*hd .. (h+1)*hd, the weights are +// heads x seq x seq, and causal masking is optional. backward is the exact +// gradient, checked against finite differences. Dropout is carried in the config +// and not applied: this is the inference computation. + module Attention; use base::types; use math::constants; @@ -10,7 +19,7 @@ module Attention; // 1. Constants // ═══════════════════════════════════════════════════════════ - const SCALE_FACTOR : f32 = 0.0; + const NEG_INF : f32 = -1.0e30; // ═══════════════════════════════════════════════════════════ // 2. Types @@ -32,232 +41,267 @@ module Attention; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(query: []const f32, key: []const f32, value: []const f32, output: []f32, weights: []f32, config: AttentionConfig) → void + fn seq_of(query: []const f32, config: AttentionConfig) -> usize { + return query.len / config.d_model; + } + + fn scale_of(config: AttentionConfig) -> f32 { + return 1.0 / sqrt(@as(f32, @floatFromInt(config.d_model / config.num_heads))); + } + fn forward(query: []const f32, key: []const f32, value: []const f32, output: []f32, weights: []f32, config: AttentionConfig) -> void { - // Compute attention scores: query · key^T - const seq_len : u32 = @intCast(query.len / config.d_model); - const head_dim : u32 = config.d_model / config.num_heads; - - // Scale query vectors - const scaled_query = []f32(query.len); - var i : u32 = 0; - while (i < query.len) : (i += 1) { - scaled_query[i] = query[i] * @floatFromInt(1) / @sqrt(@floatFromInt(head_dim)); - } - - // Compute attention weights - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var j : u32 = 0; - while (j < seq_len) : (j += 1) { - var k : u32 = 0; - var score : f32 = 0.0; - while (k < head_dim) : (k += 1) { - score += scaled_query[i * head_dim + k] * key[j * head_dim + k]; + const n = seq_of(query, config); + const d : usize = config.d_model; + const hd : usize = config.d_model / config.num_heads; + const scale = scale_of(config); + var h : usize = 0; + while (h < config.num_heads) { + var i : usize = 0; + while (i < n) { + const row = weights[(h * n + i) * n .. (h * n + i + 1) * n]; + var max_s : f32 = NEG_INF; + var j : usize = 0; + while (j < n) { + var score : f32 = NEG_INF; + if (!(config.causal and j > i)) { + score = 0.0; + var k : usize = 0; + while (k < hd) { + score = score + query[i * d + h * hd + k] * key[j * d + h * hd + k]; + k = k + 1; + } + score = score * scale; + } + row[j] = score; + max_s = @max(max_s, score); + j = j + 1; + } + var sum : f32 = 0.0; + j = 0; + while (j < n) { + row[j] = exp(row[j] - max_s); + sum = sum + row[j]; + j = j + 1; + } + j = 0; + while (j < n) { + row[j] = row[j] / sum; + j = j + 1; } - - // Apply causal masking if enabled - if (config.causal and j > i) { - score = -@infinity(); + var k : usize = 0; + while (k < hd) { + var acc : f32 = 0.0; + j = 0; + while (j < n) { + acc = acc + row[j] * value[j * d + h * hd + k]; + j = j + 1; + } + output[i * d + h * hd + k] = acc; + k = k + 1; } - - weights[i * seq_len + j] = score; + i = i + 1; } + h = h + 1; } - - // Apply softmax to get attention probabilities - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var max_score : f32 = -@infinity(); - var j : u32 = 0; - while (j < seq_len) : (j += 1) { - max_score = @max(max_score, weights[i * seq_len + j]); - } - - j = 0; - var sum_exp : f32 = 0.0; - while (j < seq_len) : (j += 1) { - weights[i * seq_len + j] = @exp(weights[i * seq_len + j] - max_score); - sum_exp += weights[i * seq_len + j]; - } - - j = 0; - while (j < seq_len) : (j += 1) { - weights[i * seq_len + j] /= sum_exp; - } + } + + // dV_j += P_ij dO_i; dP_ij = dO_i . V_j; dS_ij = P_ij (dP_ij - sum_k P_ik dP_ik); + // dQ_i += scale dS_ij K_j; dK_j += scale dS_ij Q_i (per head; masked P_ij are 0) + fn backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) -> void { + const n = seq_of(query, config); + const d : usize = config.d_model; + const hd : usize = config.d_model / config.num_heads; + const scale = scale_of(config); + var x : usize = 0; + while (x < n * d) { + grad_query[x] = 0.0; + grad_key[x] = 0.0; + grad_value[x] = 0.0; + x = x + 1; } - - // Compute weighted sum of values - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var k : u32 = 0; - while (k < head_dim) : (k += 1) { - var j : u32 = 0; - var weighted_sum : f32 = 0.0; - while (j < seq_len) : (j += 1) { - weighted_sum += weights[i * seq_len + j] * value[j * head_dim + k]; + var h : usize = 0; + while (h < config.num_heads) { + var i : usize = 0; + while (i < n) { + const p = attn_weights[(h * n + i) * n .. (h * n + i + 1) * n]; + var row_dot : f32 = 0.0; + var j : usize = 0; + while (j < n) { + var dp : f32 = 0.0; + var k : usize = 0; + while (k < hd) { + dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k]; + grad_value[j * d + h * hd + k] = grad_value[j * d + h * hd + k] + p[j] * grad_output[i * d + h * hd + k]; + k = k + 1; + } + row_dot = row_dot + p[j] * dp; + j = j + 1; } - output[i * head_dim + k] = weighted_sum; - } - } - - // Apply dropout if enabled - if (config.dropout > 0.0) { - var i : u32 = 0; - while (i < weights.len) : (i += 1) { - if (@random() < config.dropout) { - weights[i] = 0.0; + j = 0; + while (j < n) { + var dp : f32 = 0.0; + var k : usize = 0; + while (k < hd) { + dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k]; + k = k + 1; + } + const ds = p[j] * (dp - row_dot) * scale; + k = 0; + while (k < hd) { + grad_query[i * d + h * hd + k] = grad_query[i * d + h * hd + k] + ds * key[j * d + h * hd + k]; + grad_key[j * d + h * hd + k] = grad_key[j * d + h * hd + k] + ds * query[i * d + h * hd + k]; + k = k + 1; + } + j = j + 1; } + i = i + 1; } + h = h + 1; } } - // backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) → void - fn backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) -> void { - const seq_len : u32 = @intCast(query.len / config.d_model); - const head_dim : u32 = config.d_model / config.num_heads; - - // Initialize gradients to zero - var i : u32 = 0; - while (i < grad_query.len) : (i += 1) { - grad_query[i] = 0.0; + fn cfg(causal: bool, dropout: f32) -> AttentionConfig { + return AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = dropout, .causal = causal }; + } + + // The fixture: seq 3, d_model 4, 2 heads (columns 0-1 and 2-3); q / k / v scaled down so the + // softmax is not saturated. which: 0 = output, 1 = weights. + fn fixture(q: []f32, k: []f32, v: []f32) -> void { + var x : usize = 0; + while (x < 12) { + q[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + k[x] = @as(f32, @floatFromInt(x / 4 + 1)) / 4.0 - @as(f32, @floatFromInt(x % 2)) / 3.0; + v[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + x = x + 1; } - i = 0; - while (i < grad_key.len) : (i += 1) { - grad_key[i] = 0.0; + } + + fn forward_at(causal: bool, which: u8, index: usize) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + var out : [12]f32 = [9.0] ** 12; + var w : [18]f32 = [9.0] ** 18; + forward(&q, &k, &v, &out, &w, cfg(causal, 0.0)); + if (which == 0) { + return out[index]; } - i = 0; - while (i < grad_value.len) : (i += 1) { - grad_value[i] = 0.0; + return w[index]; + } + + // L = sum_x g_x O_x with g_x = (x + 1) / 10, one entry of q, k or v moved by delta + // (which: 0 = q, 1 = k, 2 = v) + fn loss(which: u8, index: usize, delta: f32) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + if (which == 0) { + q[index] = q[index] + delta; } - - // Compute gradients for value: grad_output · attention_weights^T - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var k : u32 = 0; - while (k < head_dim) : (k += 1) { - var j : u32 = 0; - while (j < seq_len) : (j += 1) { - grad_value[j * head_dim + k] += grad_output[i * head_dim + k] * attn_weights[i * seq_len + j]; - } - } + if (which == 1) { + k[index] = k[index] + delta; } - - // Compute gradients for attention weights: grad_output · value^T - var grad_weights = []f32(attn_weights.len); - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var j : u32 = 0; - while (j < seq_len) : (j += 1) { - var k : u32 = 0; - var grad_attn : f32 = 0.0; - while (k < head_dim) : (k += 1) { - grad_attn += grad_output[i * head_dim + k] * value[j * head_dim + k]; - } - grad_weights[i * seq_len + j] = grad_attn; - } + if (which == 2) { + v[index] = v[index] + delta; } - - // Compute gradients for query and key through attention weights - var i : u32 = 0; - while (i < seq_len) : (i += 1) { - var j : u32 = 0; - while (j < seq_len) : (j += 1) { - if (config.causal and j > i) { - continue; // Skip causal positions - } - - var k : u32 = 0; - while (k < head_dim) : (k += 1) { - // Gradient for query - grad_query[i * head_dim + k] += grad_weights[i * seq_len + j] * key[j * head_dim + k]; - - // Gradient for key - grad_key[j * head_dim + k] += grad_weights[i * seq_len + j] * query[i * head_dim + k]; - } - } + var out : [12]f32 = undefined; + var w : [18]f32 = undefined; + forward(&q, &k, &v, &out, &w, cfg(false, 0.0)); + var total : f32 = 0.0; + var x : usize = 0; + while (x < 12) { + total = total + @as(f32, @floatFromInt(x + 1)) / 10.0 * out[x]; + x = x + 1; } - - // Apply scaling factor to gradients - const scale : f32 = @floatFromInt(1) / @sqrt(@floatFromInt(head_dim)); - var i : u32 = 0; - while (i < grad_query.len) : (i += 1) { - grad_query[i] *= scale; + return total; + } + + fn grad(which: u8, index: usize, dropout: f32) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + var out : [12]f32 = undefined; + var w : [18]f32 = undefined; + forward(&q, &k, &v, &out, &w, cfg(false, dropout)); + var g : [12]f32 = undefined; + var x : usize = 0; + while (x < 12) { + g[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + x = x + 1; } - i = 0; - while (i < grad_key.len) : (i += 1) { - grad_key[i] *= scale; + var gq : [12]f32 = undefined; + var gk : [12]f32 = undefined; + var gv : [12]f32 = undefined; + backward(&g, &q, &k, &v, &w, &gq, &gk, &gv, cfg(false, dropout)); + if (which == 0) { + return gq[index]; } + if (which == 1) { + return gk[index]; + } + return gv[index]; + } + + fn slope(which: u8, index: usize) -> f32 { + return (loss(which, index, 0.001) - loss(which, index, -0.001)) / 0.002; + } + + fn valid_input() -> u32 { + return cfg(false, 0.0).d_model % cfg(false, 0.0).num_heads; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // Each weight row is a distribution, and each output is a weighted mean of the values + // (so it lies between the smallest and largest value in its column) test forward_basic_case { - var query: [12]f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; - var key: [12]f32 = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0]; - var value: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var config = AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = 0.0, .causal = false }; - var output: [12]f32 = [0.0] ** 12; - var weights: [9]f32 = [0.0] ** 9; - forward(&query, &key, &value, &output, &weights, config); - assert(output[0] + output[1] + output[2] + output[3] > 0.0); // computed a meaningful output + const row_sum = forward_at(false, 1, 0) + forward_at(false, 1, 1) + forward_at(false, 1, 2); + assert(@abs(row_sum - 1.0) < 0.000001); + assert(forward_at(false, 0, 0) + forward_at(false, 0, 1) + forward_at(false, 0, 2) + forward_at(false, 0, 3) > 0.0); // computed a meaningful output + assert(forward_at(false, 0, 0) > 0.1 and forward_at(false, 0, 0) < 0.9); } + // dQ, dK and dV against central differences of L = g . O test backward_basic_case { - var grad_output: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var query: [12]f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; - var key: [12]f32 = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0]; - var value: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var attn_weights: [9]f32 = [0.3, 0.3, 0.4, 0.3, 0.3, 0.4, 0.4, 0.4, 0.2]; - var config = AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = 0.0, .causal = false }; - var grad_query: [12]f32 = [0.0] ** 12; - var grad_key: [12]f32 = [0.0] ** 12; - var grad_value: [12]f32 = [0.0] ** 12; - backward(&grad_output, &query, &key, &value, &attn_weights, &grad_query, &grad_key, &grad_value, config); - assert(grad_query[0] + grad_query[1] + grad_query[2] + grad_query[3] != 0.0); // computed gradients + assert(@abs(grad(0, 0, 0.0) - slope(0, 0)) < 0.001); + assert(@abs(grad(0, 7, 0.0) - slope(0, 7)) < 0.001); + assert(@abs(grad(1, 5, 0.0) - slope(1, 5)) < 0.001); + assert(@abs(grad(2, 10, 0.0) - slope(2, 10)) < 0.001); + assert(grad(0, 0, 0.0) + grad(0, 1, 0.0) + grad(0, 2, 0.0) + grad(0, 3, 0.0) != 0.0); // computed gradients } + // Position 0 attends only to itself, position 1 to positions 0 and 1 test forward_causal_masking { - var query: [12]f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; - var key: [12]f32 = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0]; - var value: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var config = AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = 0.0, .causal = true }; - var output: [12]f32 = [0.0] ** 12; - var weights: [9]f32 = [0.0] ** 9; - forward(&query, &key, &value, &output, &weights, config); - // A position may not attend to a later one, so its weight there stays far below 1. - assert(weights[1 * 3 + 2] < 0.999); + assert(forward_at(true, 1, 0) == 1.0); + assert(forward_at(true, 1, 1) == 0.0 and forward_at(true, 1, 2) == 0.0); + assert(forward_at(true, 1, 1 * 3 + 2) < 0.999); + assert(forward_at(true, 1, 1 * 3 + 2) == 0.0); + assert(forward_at(true, 0, 0) == 0.1); } + // Dropout is not applied here (inference), so it leaves the gradients unchanged test backward_dropout { - var grad_output: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var query: [12]f32 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; - var key: [12]f32 = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0]; - var value: [12]f32 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]; - var attn_weights: [9]f32 = [0.3, 0.3, 0.4, 0.3, 0.3, 0.4, 0.4, 0.4, 0.2]; - var config = AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = 0.5, .causal = false }; - var grad_query: [12]f32 = [0.0] ** 12; - var grad_key: [12]f32 = [0.0] ** 12; - var grad_value: [12]f32 = [0.0] ** 12; - backward(&grad_output, &query, &key, &value, &attn_weights, &grad_query, &grad_key, &grad_value, config); - assert(grad_value.len == 12); + assert(grad(2, 3, 0.5) == grad(2, 3, 0.0)); + assert(grad(0, 11, 0.5) == grad(0, 11, 0.0)); } // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // d_model % num_heads == 0 invariant attention_constraint_0 - given input = valid_input() - then true // d_model % num_heads == 0 + assert valid_input() == 0 + // 0 <= dropout < 1 invariant attention_constraint_1 - given input = valid_input() - then true // 0 <= dropout < 1 + assert cfg(false, 0.5).dropout >= 0.0 and cfg(false, 0.5).dropout < 1.0 + // query.shape == key.shape == value.shape: seq is read from the query invariant attention_constraint_2 - given input = valid_input() - then true // query.shape == key.shape == value.shape - + assert cfg(false, 0.0).d_model == 4 diff --git a/apps/website/public/t27/files/specs/ml/recurrent/lstm_single.t27 b/apps/website/public/t27/files/specs/ml/recurrent/lstm_single.t27 index 0e216bac38..bc16437835 100644 --- a/apps/website/public/t27/files/specs/ml/recurrent/lstm_single.t27 +++ b/apps/website/public/t27/files/specs/ml/recurrent/lstm_single.t27 @@ -2,6 +2,15 @@ // t27/specs/ // LSTM solves vanishing gradient problem | φ² + 1/φ² = 3 | TRINITY +// #8980: called `@sigmoid` and `@tanh`, which Zig does not have; each gate weight +// was one number per INPUT, indexed `i % hidden_size`, so it was not an LSTM; and +// every test asserted `true`. Now each gate has its own matrices, W_x +// (hidden x input) and W_h (hidden x hidden), and a bias: +// i = s(z_i), f = s(z_f), g = tanh(z_g), o = s(z_o), z = W_x x + W_h h + b +// c' = f c + i g, h' = o tanh(c') +// backward gives every gradient of one step, and the tests check it against finite +// differences. + module LstmCell; use base::types; use math::constants; @@ -45,190 +54,272 @@ module LstmCell; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(input: []const f32, state: LSTMState, weights: LSTMWeights, output_state: LSTMState, config: LSTMConfig) -> void + fn sigmoid(z: f32) -> f32 { + return 1.0 / (1.0 + exp(-z)); + } + + // Pre-activation of one gate for hidden unit u: W_x[u] . x + W_h[u] . h + b[u] + fn pre(w_x: []const f32, w_h: []const f32, b: []const f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig) -> f32 { + var z : f32 = b[u]; + var j : usize = 0; + while (j < config.input_size) { + z = z + w_x[u * config.input_size + j] * x[j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + z = z + w_h[u * config.hidden_size + k] * h[k]; + k = k + 1; + } + return z; + } + fn forward(input: []const f32, state: LSTMState, weights: LSTMWeights, output_state: LSTMState, config: LSTMConfig) -> void { - // LSTM forward pass implementation - // Compute input, forget, output, and cell gates - for (0..config.input_size) |i| { - var input_val:f32 = input[i]; - - // Input gate: i = σ(W_ii * x + W_hi * h + b_i) - var input_gate:f32 = @sigmoid(weights.W_ii[i] * input_val + weights.W_hi[i] * state.h[i % config.hidden_size] + weights.b_i[i % config.hidden_size]); - - // Forget gate: f = σ(W_if * x + W_hf * h + b_f) - var forget_gate:f32 = @sigmoid(weights.W_if[i] * input_val + weights.W_hf[i] * state.h[i % config.hidden_size] + weights.b_f[i % config.hidden_size]); - - // Output gate: o = σ(W_io * x + W_ho * h + b_o) - var output_gate:f32 = @sigmoid(weights.W_io[i] * input_val + weights.W_ho[i] * state.h[i % config.hidden_size] + weights.b_o[i % config.hidden_size]); - - // Cell gate candidate: g = tanh(W_ig * x + W_hg * h + b_g) - var cell_candidate:f32 = @tanh(weights.W_ig[i] * input_val + weights.W_hg[i] * state.h[i % config.hidden_size] + weights.b_g[i % config.hidden_size]); - - // Update cell state: c = f * c + i * g - output_state.c[i % config.hidden_size] = forget_gate * state.c[i % config.hidden_size] + input_gate * cell_candidate; - - // Update hidden state: h = o * tanh(c) - output_state.h[i % config.hidden_size] = output_gate * @tanh(output_state.c[i % config.hidden_size]); + var u : usize = 0; + while (u < config.hidden_size) { + const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config)); + const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config)); + const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config)); + const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config)); + output_state.c[u] = fg * state.c[u] + ig * gg; + output_state.h[u] = og * tanh(output_state.c[u]); + u = u + 1; } } - // backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void - fn backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void { - // LSTM backward pass implementation - var config:LSTMConfig = LSTMConfig{ - .input_size = input.size(), - .hidden_size = state.h.size(), + // Adds dz * (x, h, 1) into one gate's weight gradients, and dz * W into grad_input / grad_state.h + fn spread(dz: f32, w_x: []const f32, w_h: []const f32, gw_x: []f32, gw_h: []f32, gb: []f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig, grad_input: []f32, grad_h: []f32) -> void { + var j : usize = 0; + while (j < config.input_size) { + gw_x[u * config.input_size + j] = gw_x[u * config.input_size + j] + dz * x[j]; + grad_input[j] = grad_input[j] + dz * w_x[u * config.input_size + j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + gw_h[u * config.hidden_size + k] = gw_h[u * config.hidden_size + k] + dz * h[k]; + grad_h[k] = grad_h[k] + dz * w_h[u * config.hidden_size + k]; + k = k + 1; + } + gb[u] = gb[u] + dz; + } + + // One step back. grad_output = dL/dh', grad_cell = dL/dc' from later steps. Writes + // dL/dx, dL/dh, dL/dc and ADDS the weight gradients into grad_weights. + // do = dh' tanh(c'); dc = dh' o (1 - tanh^2 c') + grad_cell + // dz_o = do o (1 - o), dz_f = dc c f (1 - f), dz_i = dc g i (1 - i), dz_g = dc i (1 - g^2) + // dL/dc = dc f + fn backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, config: LSTMConfig, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void { + var j : usize = 0; + while (j < config.input_size) { + grad_input[j] = 0.0; + j = j + 1; + } + var u : usize = 0; + while (u < config.hidden_size) { + grad_state.h[u] = 0.0; + u = u + 1; + } + u = 0; + while (u < config.hidden_size) { + const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config)); + const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config)); + const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config)); + const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config)); + const c_new = fg * state.c[u] + ig * gg; + const tc = tanh(c_new); + const dc = grad_output[u] * og * (1.0 - tc * tc) + grad_cell[u]; + const dz_o = grad_output[u] * tc * og * (1.0 - og); + const dz_f = dc * state.c[u] * fg * (1.0 - fg); + const dz_i = dc * gg * ig * (1.0 - ig); + const dz_g = dc * ig * (1.0 - gg * gg); + grad_state.c[u] = dc * fg; + spread(dz_i, weights.W_ii, weights.W_hi, grad_weights.W_ii, grad_weights.W_hi, grad_weights.b_i, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_f, weights.W_if, weights.W_hf, grad_weights.W_if, grad_weights.W_hf, grad_weights.b_f, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_g, weights.W_ig, weights.W_hg, grad_weights.W_ig, grad_weights.W_hg, grad_weights.b_g, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_o, weights.W_io, weights.W_ho, grad_weights.W_io, grad_weights.W_ho, grad_weights.b_o, input, state.h, u, config, grad_input, grad_state.h); + u = u + 1; + } + } + + // The fixture: input 3, hidden 2. All 48 weights live in one buffer, per gate + // W_x (6), W_h (4), b (2), in the gate order i, f, g, o. + fn cfg() -> LSTMConfig { + return LSTMConfig{ .input_size = 3, .hidden_size = 2 }; + } + + fn weights_of(w: []f32) -> LSTMWeights { + return LSTMWeights{ + .W_ii = w[0..6], .W_hi = w[6..10], .b_i = w[10..12], + .W_if = w[12..18], .W_hf = w[18..22], .b_f = w[22..24], + .W_ig = w[24..30], .W_hg = w[30..34], .b_g = w[34..36], + .W_io = w[36..42], .W_ho = w[42..46], .b_o = w[46..48], }; - - // Initialize gradients to zero - for (0..grad_input.size()) |i| { - grad_input[i] = 0.0; - } - - for (0..grad_state.h.size()) |i| { - grad_state.h[i] = 0.0; - grad_state.c[i] = 0.0; - } - - // Backward pass through LSTM cell - for (0..config.input_size) |i| { - var input_val:f32 = input[i]; - - // Compute forward pass gates (needed for backward pass) - var input_gate:f32 = @sigmoid(weights.W_ii[i] * input_val + weights.W_hi[i] * state.h[i % config.hidden_size] + weights.b_i[i % config.hidden_size]); - var forget_gate:f32 = @sigmoid(weights.W_if[i] * input_val + weights.W_hf[i] * state.h[i % config.hidden_size] + weights.b_f[i % config.hidden_size]); - var output_gate:f32 = @sigmoid(weights.W_io[i] * input_val + weights.W_ho[i] * state.h[i % config.hidden_size] + weights.b_o[i % config.hidden_size]); - var cell_candidate:f32 = @tanh(weights.W_ig[i] * input_val + weights.W_hg[i] * state.h[i % config.hidden_size] + weights.b_g[i % config.hidden_size]); - - // Compute derivatives - var cell_derivative:f32 = 1.0 - @tanh(state.c[i % config.hidden_size]) * @tanh(state.c[i % config.hidden_size]); - var cell_candidate_derivative:f32 = 1.0 - cell_candidate * cell_candidate; - - // Backpropagate through output gate - var output_grad:f32 = grad_output[i % config.hidden_size] * @tanh(state.c[i % config.hidden_size]) * output_gate * (1.0 - output_gate); - - // Backpropagate through cell state - var cell_grad:f32 = grad_output[i % config.hidden_size] * output_gate * cell_derivative + grad_cell[i % config.hidden_size]; - - // Backpropagate through forget gate - var forget_grad:f32 = cell_grad * state.c[i % config.hidden_size] * forget_gate * (1.0 - forget_gate); - - // Backpropagate through input gate - var input_grad:f32 = cell_grad * cell_candidate * input_gate * (1.0 - input_gate); - - // Accumulate gradients for input - grad_input[i] += input_grad * weights.W_ii[i] + forget_grad * weights.W_if[i] + output_grad * weights.W_io[i] + cell_grad * cell_candidate_derivative * weights.W_ig[i]; - - // Accumulate gradients for hidden state - grad_state.h[i % config.hidden_size] += input_grad * weights.W_hi[i] + forget_grad * weights.W_hf[i] + output_grad * weights.W_ho[i] + cell_grad * cell_candidate_derivative * weights.W_hg[i]; - - // Accumulate gradients for weights (simplified - in practice we'd sum over batch) - grad_weights.b_i[i % config.hidden_size] += input_grad; - grad_weights.b_f[i % config.hidden_size] += forget_grad; - grad_weights.b_o[i % config.hidden_size] += output_grad; - grad_weights.b_g[i % config.hidden_size] += cell_grad * cell_candidate_derivative; + } + + // Deterministic weights in [-0.5, 0.5]; the forget biases start at FORGET_BIAS_INIT + fn fill(w: []f32) -> void { + var k : usize = 0; + while (k < 48) { + w[k] = @as(f32, @floatFromInt((k * 7 + 3) % 11)) / 10.0 - 0.5; + k = k + 1; + } + w[22] = FORGET_BIAS_INIT; + w[23] = FORGET_BIAS_INIT; + } + + // L = 0.5 h'_0 - 0.3 h'_1 + 0.2 c'_0 + 0.1 c'_1 after one step, with one input, one h or + // one c entry moved by `delta` (which: 0 = none, 1 + j = x_j, 4 + k = h_k, 6 + k = c_k, + // 8 = b_f[1]) + fn loss(which: usize, delta: f32) -> f32 { + var w : [48]f32 = undefined; + fill(&w); + var x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + if (which >= 1 and which <= 3) { + x[which - 1] = x[which - 1] + delta; + } + if (which >= 4 and which <= 5) { + h[which - 4] = h[which - 4] + delta; + } + if (which >= 6 and which <= 7) { + c[which - 6] = c[which - 6] + delta; } + if (which == 8) { + w[23] = w[23] + delta; + } + var h_out : [2]f32 = [0.0] ** 2; + var c_out : [2]f32 = [0.0] ** 2; + forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg()); + return 0.5 * h_out[0] - 0.3 * h_out[1] + 0.2 * c_out[0] + 0.1 * c_out[1]; + } + + // The analytic gradient of that loss, same `which` numbering + fn grad(which: usize) -> f32 { + var w : [48]f32 = undefined; + fill(&w); + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + const grad_output : [2]f32 = [0.5, -0.3]; + const grad_cell : [2]f32 = [0.2, 0.1]; + var gx : [3]f32 = [0.0] ** 3; + var gh : [2]f32 = [0.0] ** 2; + var gc : [2]f32 = [0.0] ** 2; + var gw : [48]f32 = [0.0] ** 48; + backward(&grad_output, &grad_cell, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw)); + if (which >= 1 and which <= 3) { + return gx[which - 1]; + } + if (which >= 4 and which <= 5) { + return gh[which - 4]; + } + if (which >= 6 and which <= 7) { + return gc[which - 6]; + } + return gw[23]; + } + + // Sum of |every gradient| when grad_output and grad_cell are both 0 + fn zero_upstream_total() -> f32 { + var w : [48]f32 = undefined; + fill(&w); + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + const zeros : [2]f32 = [0.0, 0.0]; + var gx : [3]f32 = [0.0] ** 3; + var gh : [2]f32 = [0.0] ** 2; + var gc : [2]f32 = [0.0] ** 2; + var gw : [48]f32 = [0.0] ** 48; + backward(&zeros, &zeros, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw)); + var total : f32 = @abs(gx[0]) + @abs(gx[1]) + @abs(gx[2]) + @abs(gh[0]) + @abs(gh[1]) + @abs(gc[0]) + @abs(gc[1]); + var k : usize = 0; + while (k < 48) { + total = total + @abs(gw[k]); + k = k + 1; + } + return total; + } + + fn slope(which: usize) -> f32 { + return (loss(which, 0.001) - loss(which, -0.001)) / 0.002; + } + + // which: 0 = h'_0, 1 = c'_0 for a 1-unit cell with every weight 0 and the given biases + fn bias_only(b_i: f32, b_f: f32, b_g: f32, b_o: f32, c_prev: f32, which: u8) -> f32 { + var w : [48]f32 = [0.0] ** 48; + w[10] = b_i; + w[22] = b_f; + w[34] = b_g; + w[46] = b_o; + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.0, 0.0]; + var c : [2]f32 = [c_prev, 0.0]; + var h_out : [2]f32 = [9.0] ** 2; + var c_out : [2]f32 = [9.0] ** 2; + forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg()); + if (which == 0) { + return h_out[0]; + } + return c_out[0]; + } + + fn valid_input() -> usize { + return cfg().input_size; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // All weights 0: every gate is s(0) = 0.5 or tanh(0) = 0, so c' = 0.5 c and h' = 0.5 tanh(c') test forward_basic_case - given input = [1.0f32, 2.0f32, 3.0f32] - when result = forward(input) - then true // Forward pass completes without error + given c_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 1) + when h_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 0) + then @abs(c_new - 0.4) < 0.000001 and @abs(h_new - 0.5 * tanh(c_new)) < 0.000001 and @abs(h_new - 0.1899745) < 0.000001 - test backward_basic_case - given grad_output = [0.5f32, -0.3f32, 0.2f32] - when result = backward(grad_output) - then true // Backward pass completes without error + // A closed forget gate (b_f = -30) erases the old cell; an open one (b_f = 30) keeps it + test forward_basic_lstm + given erased = bias_only(0.0, -30.0, 0.0, 0.0, 0.8, 1) + when kept = bias_only(-30.0, 30.0, 0.0, 0.0, 0.8, 1) + then @abs(erased) < 0.000001 and @abs(kept - 0.8) < 0.000001 + // A closed input gate and forget gate leave c' = 0, so h' = 0 whatever the output gate does test forward_with_empty_input - given input = []f32 - when result = forward(input) - then true // Handles empty input gracefully - - test backward_with_empty_grad - given grad_output = []f32 - when result = backward(grad_output) - then true // Handles empty gradient input gracefully + given h_new = bias_only(-30.0, -30.0, 1.0, 30.0, 0.8, 0) + then @abs(h_new) < 0.000001 - test forward_basic_lstm - given - input = [1.0f32, 2.0f32, 3.0f32] - state = LSTMState{.h = [0.1f32, 0.2f32], .c = [0.3f32, 0.4f32]} - weights = LSTMWeights{ - .W_ii = [0.1f32, 0.2f32, 0.3f32], - .W_hi = [0.4f32, 0.5f32], - .b_i = [0.6f32, 0.7f32], - .W_if = [0.8f32, 0.9f32, 1.0f32], - .W_hf = [1.1f32, 1.2f32], - .b_f = [1.3f32, 1.4f32], - .W_ig = [1.5f32, 1.6f32, 1.7f32], - .W_hg = [1.8f32, 1.9f32], - .b_g = [2.0f32, 2.1f32], - .W_io = [2.2f32, 2.3f32, 2.4f32], - .W_ho = [2.5f32, 2.6f32], - .b_o = [2.7f32, 2.8f32], - } - output_state = LSTMState{.h = [0.0f32, 0.0f32], .c = [0.0f32, 0.0f32]} - config = LSTMConfig{.input_size = 3, .hidden_size = 2} - when result = forward(input, state, weights, output_state, config) - then true // Forward pass completes without error + // dL/dx_j against central differences + test backward_basic_case + given g0 = grad(1) + when g2 = grad(3) + then @abs(g0 - slope(1)) < 0.0005 and @abs(grad(2) - slope(2)) < 0.0005 and @abs(g2 - slope(3)) < 0.0005 + // dL/dh_k, dL/dc_k and dL/db_f[1] against central differences test backward_basic_lstm - given - grad_output = [0.5f32, -0.3f32] - grad_cell = [0.2f32, 0.1f32] - input = [1.0f32, 2.0f32, 3.0f32] - state = LSTMState{.h = [0.1f32, 0.2f32], .c = [0.3f32, 0.4f32]} - weights = LSTMWeights{ - .W_ii = [0.1f32, 0.2f32, 0.3f32], - .W_hi = [0.4f32, 0.5f32], - .b_i = [0.6f32, 0.7f32], - .W_if = [0.8f32, 0.9f32, 1.0f32], - .W_hf = [1.1f32, 1.2f32], - .b_f = [1.3f32, 1.4f32], - .W_ig = [1.5f32, 1.6f32, 1.7f32], - .W_hg = [1.8f32, 1.9f32], - .b_g = [2.0f32, 2.1f32], - .W_io = [2.2f32, 2.3f32, 2.4f32], - .W_ho = [2.5f32, 2.6f32], - .b_o = [2.7f32, 2.8f32], - } - grad_input = [0.0f32, 0.0f32, 0.0f32] - grad_state = LSTMState{.h = [0.0f32, 0.0f32], .c = [0.0f32, 0.0f32]} - grad_weights = LSTMWeights{ - .W_ii = [0.0f32, 0.0f32, 0.0f32], - .W_hi = [0.0f32, 0.0f32], - .b_i = [0.0f32, 0.0f32], - .W_if = [0.0f32, 0.0f32, 0.0f32], - .W_hf = [0.0f32, 0.0f32], - .b_f = [0.0f32, 0.0f32], - .W_ig = [0.0f32, 0.0f32, 0.0f32], - .W_hg = [0.0f32, 0.0f32], - .b_g = [0.0f32, 0.0f32], - .W_io = [0.0f32, 0.0f32, 0.0f32], - .W_ho = [0.0f32, 0.0f32], - .b_o = [0.0f32, 0.0f32], - } - when result = backward(grad_output, grad_cell, input, state, weights, grad_input, grad_state, grad_weights) - then true // Backward pass completes without error + given gh0 = grad(4) + when gc1 = grad(7) + then @abs(gh0 - slope(4)) < 0.0005 and @abs(grad(5) - slope(5)) < 0.0005 and @abs(grad(6) - slope(6)) < 0.0005 and @abs(gc1 - slope(7)) < 0.0005 and @abs(grad(8) - slope(8)) < 0.0005 + + // With no upstream gradient nothing flows back + test backward_with_empty_grad + given total = zero_upstream_total() + then total == 0.0 and @abs(grad(1)) > 0.0 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // input.size() == config.input_size invariant lstm_cell_constraint_0 - given input = valid_input() - then true // input.size() == config.input_size + assert valid_input() == 3 + // state.h.size() == config.hidden_size invariant lstm_cell_constraint_1 - given input = valid_input() - then true // state.h.size() == config.hidden_size + assert cfg().hidden_size == 2 + // state.c.size() == config.hidden_size; the forget bias starts open invariant lstm_cell_constraint_2 - given input = valid_input() - then true // state.c.size() == config.hidden_size - + assert FORGET_BIAS_INIT > 0.0 diff --git a/apps/website/public/t27/files/specs/ml/recurrent/rnn_cell.t27 b/apps/website/public/t27/files/specs/ml/recurrent/rnn_cell.t27 index 56e54d7a3f..0ad0f92fae 100644 --- a/apps/website/public/t27/files/specs/ml/recurrent/rnn_cell.t27 +++ b/apps/website/public/t27/files/specs/ml/recurrent/rnn_cell.t27 @@ -2,6 +2,12 @@ // t27/specs/ // Basic RNN recurrence equation | φ² + 1/φ² = 3 | TRINITY +// #8980: written against undeclared `matmul`, `add`, `zeros`, `len` and `append`, +// it applied tanh twice (h = tanh(tanh(z))), and the tests asserted +// `result != undefined`. It is now the Elman cell, +// h' = tanh(W_x x + W_h h + b), with W_x hidden x input and W_h hidden x hidden +// (row-major), stepping over buffers the caller owns. + module RnnCell; use base::types; use math::constants; @@ -37,99 +43,148 @@ module RnnCell; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward_step(input: []f32, state: RNNState, params: RNNParams) -> RNNState - fn forward_step(input: []f32, state: RNNState, params: RNNParams) -> RNNState { - // Basic RNN forward step implementation - // Apply linear transformation to input - let input_transformed: []f32 = matmul(params.w_x, input); - - // Apply linear transformation to hidden state - let hidden_transformed: []f32 = matmul(params.w_h, state.hidden); - - // Add bias and apply activation function (tanh for cell state) - let cell_input: []f32 = add(add(input_transformed, hidden_transformed), params.b); - let new_cell: []f32 = tanh(cell_input); - - // Apply activation function (tanh) for hidden state - let new_hidden: []f32 = tanh(new_cell); - - return RNNState { - hidden: new_hidden, - cell: new_cell, - }; + // new_hidden[i] = tanh(sum_j W_x[i][j] x[j] + sum_k W_h[i][k] h[k] + b[i]) + fn forward_step(input: []const f32, hidden: []const f32, params: RNNParams, config: RNNCellConfig, new_hidden: []f32) -> void { + var i : usize = 0; + while (i < config.hidden_size) { + var z : f32 = params.b[i]; + var j : usize = 0; + while (j < config.input_size) { + z = z + params.w_x[i * config.input_size + j] * input[j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + z = z + params.w_h[i * config.hidden_size + k] * hidden[k]; + k = k + 1; + } + new_hidden[i] = tanh(z); + i = i + 1; + } + } + + // inputs: steps x input_size; outputs: steps x hidden_size, row t = h after step t. + // The state starts at initial_state and each step reads the previous row. + fn forward_sequence(inputs: []const f32, steps: usize, initial_state: []const f32, params: RNNParams, config: RNNCellConfig, outputs: []f32) -> void { + const n_in : usize = config.input_size; + const n_h : usize = config.hidden_size; + var t : usize = 0; + while (t < steps) { + if (t == 0) { + forward_step(inputs[0..n_in], initial_state, params, config, outputs[0..n_h]); + } else { + forward_step(inputs[t * n_in .. (t + 1) * n_in], outputs[(t - 1) * n_h .. t * n_h], params, config, outputs[t * n_h .. (t + 1) * n_h]); + } + t = t + 1; + } + } + + // The first hidden_size entries of `buffer`, zeroed + fn init_state(buffer: []f32, hidden_size: u32) -> []f32 { + var i : usize = 0; + while (i < hidden_size) { + buffer[i] = 0.0; + i = i + 1; + } + return buffer[0..hidden_size]; + } + + // A 1-in, 1-hidden cell with W_x = 1, W_h = 0.5, b = 0: h' = tanh(x + 0.5 h) + fn tiny() -> RNNCellConfig { + return RNNCellConfig{ .input_size = 1, .hidden_size = 1 }; + } + + fn tiny_step(x: f32, h: f32) -> f32 { + var w_x : [1]f32 = [1.0]; + var w_h : [1]f32 = [0.5]; + var b : [1]f32 = [0.0]; + const input : [1]f32 = [x]; + const hidden : [1]f32 = [h]; + var out : [1]f32 = [9.0]; + forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &out); + return out[0]; + } + + // The sequence (1, 0, 0) from h = 0: h after step t + fn tiny_sequence(t: usize) -> f32 { + var w_x : [1]f32 = [1.0]; + var w_h : [1]f32 = [0.5]; + var b : [1]f32 = [0.0]; + const inputs : [3]f32 = [1.0, 0.0, 0.0]; + const h0 : [1]f32 = [0.0]; + var outputs : [3]f32 = [9.0] ** 3; + forward_sequence(&inputs, 3, &h0, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &outputs); + return outputs[t]; + } + + // A 2-in, 2-hidden cell: h' = tanh(W_x x + W_h h + b) with W_x = [[1, -1], [0.5, 0.5]], + // W_h = [[0.1, 0], [0, 0.1]], b = (0, -0.5), at x = (1, 2), h = (1, -1) + fn wide_step(index: usize) -> f32 { + var w_x : [4]f32 = [1.0, -1.0, 0.5, 0.5]; + var w_h : [4]f32 = [0.1, 0.0, 0.0, 0.1]; + var b : [2]f32 = [0.0, -0.5]; + const input : [2]f32 = [1.0, 2.0]; + const hidden : [2]f32 = [1.0, -1.0]; + var out : [2]f32 = [9.0] ** 2; + forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, RNNCellConfig{ .input_size = 2, .hidden_size = 2 }, &out); + return out[index]; } - // forward_sequence(inputs: [][]f32, initial_state: []f32, params: RNNParams) -> [][]f32 - fn forward_sequence(inputs: [][]f32, initial_state: []f32, params: RNNParams) -> [][]f32 { - // Basic RNN sequence processing implementation - let sequence_length = len(inputs); - let mut output_sequence: [][]f32 = []; - - // Initialize initial state - let mut current_state = RNNState { - hidden: initial_state, - cell: zeros(len(initial_state)), - }; - - // Process each input in sequence - for i in 0..sequence_length { - current_state = forward_step(inputs[i], current_state, params); - output_sequence = append(output_sequence, current_state.hidden); + fn init_len(hidden_size: u32) -> usize { + var buffer : [64]f32 = [9.0] ** 64; + const h = init_state(&buffer, hidden_size); + if (h[hidden_size - 1] != 0.0) { + return 0; } - - return output_sequence; + return h.len; } - // init_state(hidden_size: u32) -> []f32 - fn init_state(hidden_size: u32) -> []f32 { - // Initialize RNN state with zeros - return zeros(hidden_size); + fn valid_input() -> f32 { + return tiny_step(1.0, 0.0); } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // z = (1 - 2 + 0.1, 0.5 + 1 - 0.1 - 0.5) = (-0.9, 0.9): h' = (tanh(-0.9), tanh(0.9)) test forward_step_basic_case - given input = default_input() - state = default_state() - params = default_params() - when result = forward_step(input, state, params) - then result != undefined + given h0 = wide_step(0) + when h1 = wide_step(1) + then @abs(h0 + 0.7162979) < 0.000001 and @abs(h1 - 0.7162979) < 0.000001 and @abs(tiny_step(1.0, 0.0) - 0.7615942) < 0.000001 + // The cell remembers: after the input pulse, h decays through the recurrent weight, + // h1 = tanh(1), h2 = tanh(0.5 h1), h3 = tanh(0.5 h2) test forward_sequence_basic_case - given inputs = default_sequence_inputs() - initial_state = default_input() - params = default_params() - when result = forward_sequence(inputs, initial_state, params) - then result != undefined + given h1 = tiny_sequence(0) + when h3 = tiny_sequence(2) + then @abs(h1 - 0.7615942) < 0.000001 and @abs(tiny_sequence(1) - tanh(0.5 * h1)) < 0.000001 and @abs(h3 - tanh(0.5 * tiny_sequence(1))) < 0.000001 and h3 > 0.0 and h3 < tiny_sequence(1) test init_state_basic_case given hidden_size = 64 - when result = init_state(hidden_size) - then result != undefined - then len(result) == hidden_size + when result = init_len(hidden_size) + then result == hidden_size // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // input_size >= 1 invariant rnn_cell_constraint_0 - given input = valid_input() - then true // input_size >= 1 + assert DEFAULT_INPUT_SIZE >= 1 + // hidden_size >= 1 invariant rnn_cell_constraint_1 - given input = valid_input() - then true // hidden_size >= 1 + assert DEFAULT_HIDDEN_SIZE >= 1 + // name: rnn_formula -- one tanh, not two: tanh(1) = 0.7615942, tanh(tanh(1)) = 0.6420 invariant rnn_cell_constraint_2 - given input = valid_input() - then true // name: rnn_formula + assert valid_input() > 0.76 and valid_input() < 0.77 + // "Elman (1990) - Finding Structure in Time": the state carries the past forward invariant rnn_cell_constraint_3 - given input = valid_input() - then true // "Elman (1990) - Finding Structure in Time" + assert tiny_step(0.0, 1.0) > 0.0 + // "Goodfellow et al. (2016) - Sequence Modeling with RNNs and LSTMs": tanh bounds the state invariant rnn_cell_constraint_4 - given input = valid_input() - then true // "Goodfellow et al. (2016) - Sequence Modeling with RNNs and LSTMs" \ No newline at end of file + assert tiny_step(100.0, 1.0) <= 1.0 and tiny_step(-100.0, -1.0) >= -1.0 diff --git a/apps/website/public/t27/files/specs/ml/rl/ppo_clip_loss.t27 b/apps/website/public/t27/files/specs/ml/rl/ppo_clip_loss.t27 index 637f851d91..72d30bb304 100644 --- a/apps/website/public/t27/files/specs/ml/rl/ppo_clip_loss.t27 +++ b/apps/website/public/t27/files/specs/ml/rl/ppo_clip_loss.t27 @@ -2,6 +2,15 @@ // t27/specs/ // Probability ratio between policies | φ² + 1/φ² = 3 | TRINITY +// #8980: written with `let x = if ... {}` and `for i in 0..n`, so it never compiled. +// Three formulas were wrong, and their tests pinned the wrong values: +// - compute_ratio returned log pi_new - log pi_old; the ratio is exp of that. +// - clipped_surrogate returned clip(r) A; PPO's term is min(r A, clip(r) A), so +// r = 1.1 inside the clip range gives 2.2, not 2.4. +// - policy_loss returned the surrogate itself, a quantity to MAXIMISE; as a loss +// added to the value and entropy losses it is minus the mean surrogate. +// Each test now states the value PPO defines (Schulman et al., 2017). + module PpoClipLoss; use base::types; use math::constants; @@ -36,68 +45,72 @@ module PpoClipLoss; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // compute_ratio(new_log_prob: f32, old_log_prob: f32) → f32 + // r = pi_new / pi_old = exp(log pi_new - log pi_old) fn compute_ratio(new_log_prob: f32, old_log_prob: f32) -> f32 { - // Compute probability ratio between new and old policies - return new_log_prob - old_log_prob; + return exp(new_log_prob - old_log_prob); } - // clipped_surrogate(ratio: f32, advantage: f32, clip_epsilon: f32) → f32 + // min(r A, clip(r, 1 - eps, 1 + eps) A) fn clipped_surrogate(ratio: f32, advantage: f32, clip_epsilon: f32) -> f32 { - // Apply clipping to the surrogate objective - let clipped_ratio = if ratio > 1.0 + clip_epsilon { - 1.0 + clip_epsilon - } else if ratio < 1.0 - clip_epsilon { - 1.0 - clip_epsilon - } else { - ratio - }; - return clipped_ratio * advantage; + const clipped_ratio = @min(@max(ratio, 1.0 - clip_epsilon), 1.0 + clip_epsilon); + return @min(ratio * advantage, clipped_ratio * advantage); } - // policy_loss(ratios: []f32, advantages: []f32, clip_epsilon: f32) → f32 - fn policy_loss(ratios: []f32, advantages: []f32, clip_epsilon: f32) -> f32 { - // Compute policy loss using clipped surrogate objective - let total_loss = 0.0; - for i in 0..ratios.len { - let ratio = ratios[i]; - let advantage = advantages[i]; - let clipped_loss = clipped_surrogate(ratio, advantage, clip_epsilon); - total_loss += clipped_loss; + // -mean_t min(r_t A_t, clip(r_t) A_t): the loss gradient descent minimises + fn policy_loss(ratios: []const f32, advantages: []const f32, clip_epsilon: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < ratios.len) { + total = total + clipped_surrogate(ratios[i], advantages[i], clip_epsilon); + i = i + 1; } - return total_loss / f32(ratios.len); + return -total / @as(f32, @floatFromInt(ratios.len)); } - // entropy_loss(entropies: []f32, entropy_coef: f32) → f32 - fn entropy_loss(entropies: []f32, entropy_coef: f32) -> f32 { - // Compute entropy loss to encourage exploration - let total_entropy = 0.0; - for entropy in entropies { - total_entropy += entropy; + // -coef * mean entropy: lower loss for a more exploratory policy + fn entropy_loss(entropies: []const f32, entropy_coef: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < entropies.len) { + total = total + entropies[i]; + i = i + 1; } - return -entropy_coef * (total_entropy / f32(entropies.len)); + return -entropy_coef * (total / @as(f32, @floatFromInt(entropies.len))); } - // value_loss(predicted_values: []f32, target_values: []f32, old_values: []f32, clip_coef: f32) → f32 - fn value_loss(predicted_values: []f32, target_values: []f32, old_values: []f32, clip_coef: f32) -> f32 { - // Compute value loss using clipped value function - let total_loss = 0.0; - for i in 0..predicted_values.len { - let predicted = predicted_values[i]; - let target = target_values[i]; - let old = old_values[i]; - let value_diff = predicted - old; - let clipped_value_diff = if value_diff > clip_coef { - clip_coef - } else if value_diff < -clip_coef { - -clip_coef - } else { - value_diff - }; - let value_loss = 0.5 * (target - (old + clipped_value_diff)) * (target - (old + clipped_value_diff)); - total_loss += value_loss; + // mean 0.5 (target - (old + clip(pred - old, -c, c)))^2 + fn value_loss(predicted_values: []const f32, target_values: []const f32, old_values: []const f32, clip_coef: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < predicted_values.len) { + const diff = @min(@max(predicted_values[i] - old_values[i], -clip_coef), clip_coef); + const err = target_values[i] - (old_values[i] + diff); + total = total + 0.5 * err * err; + i = i + 1; } - return total_loss / f32(predicted_values.len); + return total / @as(f32, @floatFromInt(predicted_values.len)); + } + + fn policy_loss_of(r0: f32, r1: f32, r2: f32) -> f32 { + const ratios : [3]f32 = [r0, r1, r2]; + const advantages : [3]f32 = [2.0, 1.5, 3.0]; + return policy_loss(&ratios, &advantages, DEFAULT_CLIP_EPSILON); + } + + fn entropy_loss_of() -> f32 { + const entropies : [3]f32 = [0.5, 0.6, 0.4]; + return entropy_loss(&entropies, DEFAULT_ENTROPY_COEF); + } + + fn value_loss_of(p0: f32) -> f32 { + const predicted : [3]f32 = [p0, 2.0, 1.5]; + const target : [3]f32 = [1.1, 2.1, 1.6]; + const old : [3]f32 = [0.9, 1.9, 1.4]; + return value_loss(&predicted, &target, &old, 0.2); + } + + fn valid_input() -> f32 { + return DEFAULT_CLIP_EPSILON; } // total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) → f32 @@ -115,7 +128,7 @@ module PpoClipLoss; new_log_prob = 0.5 old_log_prob = 0.3 when result = compute_ratio(new_log_prob, old_log_prob) - then result == 0.2 + then @abs(result - 1.2214028) < 0.000001 // exp(0.2); the old `== 0.2` was the log ratio test clipped_surrogate_basic_case given @@ -123,7 +136,7 @@ module PpoClipLoss; advantage = 2.0 clip_epsilon = 0.2 when result = clipped_surrogate(ratio, advantage, clip_epsilon) - then result == 1.2 * 2.0 + then @abs(result - 1.1 * 2.0) < 0.000001 // inside [0.8, 1.2] the clip does nothing test clipped_surrogate_clipping_case given @@ -131,31 +144,23 @@ module PpoClipLoss; advantage = 2.0 clip_epsilon = 0.2 when result = clipped_surrogate(ratio, advantage, clip_epsilon) - then result == 1.2 * 2.0 + then @abs(result - 1.2 * 2.0) < 0.000001 and clipped_surrogate(0.5, -1.0, 0.2) == -0.8 + // min(r A, clip(r) A) = (2.0, 1.65, 2.7): the loss is -mean = -2.1166667. The old `> 0` was + // the surrogate's sign; a ratio pushed past the clip earns nothing more. test policy_loss_basic_case - given - ratios = [1.0, 1.1, 0.9] - advantages = [2.0, 1.5, 3.0] - clip_epsilon = 0.2 - when result = policy_loss(ratios, advantages, clip_epsilon) - then result > 0.0 + given result = policy_loss_of(1.0, 1.1, 0.9) + when pushed = policy_loss_of(1.0, 1.1, 3.0) + then result < 0.0 and @abs(result + 2.1166667) < 0.000001 and @abs(pushed - policy_loss_of(1.0, 1.1, 1.2)) < 0.000001 test entropy_loss_basic_case - given - entropies = [0.5, 0.6, 0.4] - entropy_coef = 0.01 - when result = entropy_loss(entropies, entropy_coef) - then result < 0.0 + given result = entropy_loss_of() + then result < 0.0 and @abs(result + 0.005) < 0.0000001 test value_loss_basic_case - given - predicted_values = [1.0, 2.0, 1.5] - target_values = [1.1, 2.1, 1.6] - old_values = [0.9, 1.9, 1.4] - clip_coef = 0.2 - when result = value_loss(predicted_values, target_values, old_values, clip_coef) - then result > 0.0 + given result = value_loss_of(1.0) + when clipped = value_loss_of(5.0) + then result > 0.0 and @abs(result - 0.005) < 0.0000001 and @abs(clipped - value_loss_of(1.1)) < 0.0000001 test total_loss_basic_case given @@ -164,29 +169,29 @@ module PpoClipLoss; entropy_loss_value = -0.01 value_loss_coef = 0.5 when result = total_loss(policy_loss_value, value_loss_value, entropy_loss_value, value_loss_coef) - then result == 1.0 + 0.5 * 0.5 + (-0.01) + then @abs(result - (1.0 + 0.5 * 0.5 + (-0.01))) < 0.0000001 // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // 0 < clip_epsilon <= 1 (typically 0.1-0.3) invariant ppo_clip_loss_constraint_0 - given input = valid_input() - then true // 0 < clip_epsilon <= 1 (typically 0.1-0.3) + assert valid_input() > 0.0 and valid_input() <= 1.0 + // entropy_coef >= 0 invariant ppo_clip_loss_constraint_1 - given input = valid_input() - then true // entropy_coef >= 0 + assert DEFAULT_ENTROPY_COEF >= 0.0 + // name: ppo_objective -- for A > 0 the surrogate stops growing at r = 1 + eps invariant ppo_clip_loss_constraint_2 - given input = valid_input() - then true // name: ppo_objective + assert clipped_surrogate(5.0, 1.0, 0.2) == 1.2 + // name: probability_ratio -- equal log-probabilities give r = 1 invariant ppo_clip_loss_constraint_3 - given input = valid_input() - then true // name: probability_ratio + assert compute_ratio(0.3, 0.3) == 1.0 + // "Schulman et al. (2017) - Proximal Policy Optimization Algorithms, arXiv:1707.06347": + // for A < 0 the surrogate stops falling at r = 1 - eps invariant ppo_clip_loss_constraint_4 - given input = valid_input() - then true // "Schulman et al. (2017) - Proximal Policy Optimization Algorithms, arXiv:1707.06347" - + assert clipped_surrogate(0.1, -1.0, 0.2) == -0.8 diff --git a/apps/website/public/t27/files/specs/ml/transformer/encoder_block.t27 b/apps/website/public/t27/files/specs/ml/transformer/encoder_block.t27 index bedc26f64c..1ced0caac4 100644 --- a/apps/website/public/t27/files/specs/ml/transformer/encoder_block.t27 +++ b/apps/website/public/t27/files/specs/ml/transformer/encoder_block.t27 @@ -2,6 +2,14 @@ // t27/specs/ // Standard Transformer encoder block with residual connections | φ² + 1/φ² = 3 | TRINITY +// #8980: attention and the FFN returned their input ("in real implementation +// ..."), forward skipped both residuals, and the tests asked only for a non-empty +// output from undeclared `default_input()`. The block now computes the Transformer +// encoder layer over a seq x d_model input. Attention is multi-head scaled +// dot-product, softmax(q k^T / sqrt(d_head)) v per head, with identity projections. +// Then come the position-wise FFN and two residual + layer-norm steps: post-norm +// LN(x + f(x)) by default, pre-norm x + f(LN(x)) when use_pre_norm is set. + module EncoderBlock; use base::types; use math::constants; @@ -27,105 +35,337 @@ module EncoderBlock; use_pre_norm : bool, }; - pub const AttentionOutput = struct { - output : []f32, - attn_weights : [][]f32, - }; - - pub const FFNOutput = struct { - output : []f32, - }; - - pub const BlockOutput = struct { - output : []f32, + pub const FFNWeights = struct { + w1 : []const f32, + b1 : []const f32, + w2 : []const f32, + b2 : []const f32, }; // ═══════════════════════════════════════════════════════════ // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // multi_head_attention(query: []f32, key: []f32, value: []f32, n_heads: u32, d_model: u32) → AttentionOutput - fn multi_head_attention(query: []f32, key: []f32, value: []f32, n_heads: u32, d_model: u32) -> AttentionOutput { - // Basic multi-head attention implementation - // For now, return a simple identity transformation - let output = query; // In real implementation, this would be the attention output - let attn_weights = []; // In real implementation, this would contain attention weights - - return AttentionOutput { - output: output, - attn_weights: attn_weights, - }; + // q, k, v and out are seq x d_model; attn_weights is n_heads x seq x seq. Head h uses + // columns h * d_head .. (h + 1) * d_head. + fn multi_head_attention(query: []const f32, key: []const f32, value: []const f32, seq: usize, n_heads: u32, d_model: u32, out: []f32, attn_weights: []f32) -> void { + const d_head : usize = d_model / n_heads; + const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d_head))); + var h : usize = 0; + while (h < n_heads) { + var i : usize = 0; + while (i < seq) { + const row = attn_weights[(h * seq + i) * seq .. (h * seq + i + 1) * seq]; + var max_s : f32 = -1.0e30; + var j : usize = 0; + while (j < seq) { + var dot : f32 = 0.0; + var c : usize = 0; + while (c < d_head) { + dot = dot + query[i * d_model + h * d_head + c] * key[j * d_model + h * d_head + c]; + c = c + 1; + } + row[j] = dot * scale; + max_s = @max(max_s, row[j]); + j = j + 1; + } + var sum : f32 = 0.0; + j = 0; + while (j < seq) { + row[j] = exp(row[j] - max_s); + sum = sum + row[j]; + j = j + 1; + } + var c : usize = 0; + while (c < d_head) { + var acc : f32 = 0.0; + j = 0; + while (j < seq) { + acc = acc + row[j] / sum * value[j * d_model + h * d_head + c]; + j = j + 1; + } + out[i * d_model + h * d_head + c] = acc; + c = c + 1; + } + j = 0; + while (j < seq) { + row[j] = row[j] / sum; + j = j + 1; + } + i = i + 1; + } + h = h + 1; + } + } + + // out = W2 relu(W1 x + b1) + b2 for one row; hidden is d_ff floats of scratch. + // Dropout is the identity at inference, which is what this block computes. + fn feed_forward(input: []const f32, weights: FFNWeights, d_model: u32, d_ff: u32, hidden: []f32, out: []f32) -> void { + var f : usize = 0; + while (f < d_ff) { + var z : f32 = weights.b1[f]; + var j : usize = 0; + while (j < d_model) { + z = z + weights.w1[f * d_model + j] * input[j]; + j = j + 1; + } + hidden[f] = @max(z, 0.0); + f = f + 1; + } + var o : usize = 0; + while (o < d_model) { + var y : f32 = weights.b2[o]; + f = 0; + while (f < d_ff) { + y = y + weights.w2[o * d_ff + f] * hidden[f]; + f = f + 1; + } + out[o] = y; + o = o + 1; + } + } + + // (x - mean) / sqrt(var + 1e-5), no learned scale or shift + fn layer_norm(x: []const f32, out: []f32) -> void { + var mean : f32 = 0.0; + var k : usize = 0; + while (k < x.len) { + mean = mean + x[k]; + k = k + 1; + } + mean = mean / @as(f32, @floatFromInt(x.len)); + var variance : f32 = 0.0; + k = 0; + while (k < x.len) { + variance = variance + (x[k] - mean) * (x[k] - mean); + k = k + 1; + } + variance = variance / @as(f32, @floatFromInt(x.len)); + k = 0; + while (k < x.len) { + out[k] = (x[k] - mean) / sqrt(variance + 0.00001); + k = k + 1; + } + } + + // input and out are seq x d_model. scratch needs 3 seq d_model + n_heads seq^2 + d_ff + d_model floats. + fn forward(input: []const f32, seq: usize, ffn: FFNWeights, config: EncoderBlockConfig, out: []f32, scratch: []f32) -> void { + const n : usize = seq * config.d_model; + const d : usize = config.d_model; + const normed = scratch[0..n]; + const attn = scratch[n .. 2 * n]; + const mid = scratch[2 * n .. 3 * n]; + const weights = scratch[3 * n .. 3 * n + config.n_heads * seq * seq]; + const rest = 3 * n + config.n_heads * seq * seq; + const hidden = scratch[rest .. rest + config.d_ff]; + const row = scratch[rest + config.d_ff .. rest + config.d_ff + d]; + var t : usize = 0; + if (config.use_pre_norm) { + while (t < seq) { + layer_norm(input[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]); + t = t + 1; + } + multi_head_attention(normed, normed, normed, seq, config.n_heads, config.d_model, attn, weights); + var k : usize = 0; + while (k < n) { + mid[k] = input[k] + attn[k]; + k = k + 1; + } + t = 0; + while (t < seq) { + layer_norm(mid[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]); + feed_forward(normed[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row); + var c : usize = 0; + while (c < d) { + out[t * d + c] = mid[t * d + c] + row[c]; + c = c + 1; + } + t = t + 1; + } + return; + } + multi_head_attention(input, input, input, seq, config.n_heads, config.d_model, attn, weights); + var k : usize = 0; + while (k < n) { + normed[k] = input[k] + attn[k]; + k = k + 1; + } + t = 0; + while (t < seq) { + layer_norm(normed[t * d .. (t + 1) * d], mid[t * d .. (t + 1) * d]); + feed_forward(mid[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row); + var c : usize = 0; + while (c < d) { + normed[t * d + c] = mid[t * d + c] + row[c]; + c = c + 1; + } + layer_norm(normed[t * d .. (t + 1) * d], out[t * d .. (t + 1) * d]); + t = t + 1; + } + } + + // The fixture: seq 3, d_model 4, 2 heads, d_ff 8 + fn cfg(pre_norm: bool) -> EncoderBlockConfig { + return EncoderBlockConfig{ .d_model = 4, .n_heads = 2, .d_ff = 8, .dropout = DEFAULT_DROPOUT, .use_pre_norm = pre_norm }; } - // feed_forward(input: []f32, d_model: u32, d_ff: u32, dropout: f32) → FFNOutput - fn feed_forward(input: []f32, d_model: u32, d_ff: u32, dropout: f32) -> FFNOutput { - // Basic feed-forward network implementation - // For now, return a simple identity transformation - // In real implementation, this would be: Linear → ReLU → Linear → Dropout - - return FFNOutput { - output: input, // In real implementation, this would be the FFN output - }; + fn fixture_input(x: []f32) -> void { + const v : [12]f32 = [1.0, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 2.0, 1.0, 1.0, 0.0, 0.0]; + var k : usize = 0; + while (k < 12) { + x[k] = v[k]; + k = k + 1; + } } - // forward(input: []f32, config: EncoderBlockConfig) → BlockOutput - fn forward(input: []f32, config: EncoderBlockConfig) -> BlockOutput { - // Basic encoder block forward pass implementation - // Standard transformer block: x → LayerNorm → Attention → Add → LayerNorm → FFN → Add - - // Apply multi-head attention with residual connection - let attn_output = multi_head_attention(input, input, input, config.n_heads, config.d_model); - let attn_with_residual = attn_output.output; // In real implementation: add input here - - // Apply feed-forward network with residual connection - let ffn_output = feed_forward(attn_with_residual, config.d_model, config.d_ff, config.dropout); - let final_output = ffn_output.output; // In real implementation: add attn_with_residual here - - return BlockOutput { - output: final_output, - }; + // which: 0 = out[index], 1 = attn_weights[index] of self-attention on the fixture + fn attention_at(which: u8, index: usize) -> f32 { + var x : [12]f32 = undefined; + fixture_input(&x); + var out : [12]f32 = [9.0] ** 12; + var weights : [18]f32 = [9.0] ** 18; + multi_head_attention(&x, &x, &x, 3, 2, 4, &out, &weights); + if (which == 0) { + return out[index]; + } + return weights[index]; + } + + // Two keys equal: attention splits evenly and returns the mean of the values + fn tie_attention(index: usize) -> f32 { + const q : [2]f32 = [1.0, 1.0]; + const k : [2]f32 = [2.0, 2.0]; + const v : [2]f32 = [4.0, 10.0]; + var out : [2]f32 = [0.0] ** 2; + var weights : [4]f32 = [0.0] ** 4; + multi_head_attention(&q, &k, &v, 2, 1, 1, &out, &weights); + return out[index]; + } + + fn ffn_fill(w1: []f32, b1: []f32, w2: []f32, b2: []f32) -> void { + var k : usize = 0; + while (k < 32) { + w1[k] = @as(f32, @floatFromInt((k * 5 + 1) % 9)) / 8.0 - 0.5; + w2[k] = @as(f32, @floatFromInt((k * 7 + 2) % 9)) / 8.0 - 0.5; + k = k + 1; + } + k = 0; + while (k < 8) { + b1[k] = 0.1; + k = k + 1; + } + k = 0; + while (k < 4) { + b2[k] = -0.1; + k = k + 1; + } + } + + // which: 0 = out[index]; 1 = mean of row `index`; 2 = variance of row `index` + fn block_at(pre_norm: bool, which: u8, index: usize) -> f32 { + var x : [12]f32 = undefined; + fixture_input(&x); + var w1 : [32]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [32]f32 = undefined; + var b2 : [4]f32 = undefined; + ffn_fill(&w1, &b1, &w2, &b2); + var out : [12]f32 = [9.0] ** 12; + var scratch : [3 * 12 + 18 + 8 + 4]f32 = undefined; + forward(&x, 3, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, cfg(pre_norm), &out, &scratch); + if (which == 0) { + return out[index]; + } + var mean : f32 = 0.0; + var c : usize = 0; + while (c < 4) { + mean = mean + out[index * 4 + c] / 4.0; + c = c + 1; + } + if (which == 1) { + return mean; + } + var variance : f32 = 0.0; + c = 0; + while (c < 4) { + variance = variance + (out[index * 4 + c] - mean) * (out[index * 4 + c] - mean) / 4.0; + c = c + 1; + } + return variance; + } + + // FFN on row (1, 0, 0.5, -1) of the fixture weights; out[index] + fn ffn_at(index: usize) -> f32 { + var w1 : [32]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [32]f32 = undefined; + var b2 : [4]f32 = undefined; + ffn_fill(&w1, &b1, &w2, &b2); + const x : [4]f32 = [1.0, 0.0, 0.5, -1.0]; + var hidden : [8]f32 = undefined; + var out : [4]f32 = [9.0] ** 4; + feed_forward(&x, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, 4, 8, &hidden, &out); + return out[index]; + } + + fn valid_input() -> u32 { + return DEFAULT_D_MODEL / DEFAULT_N_HEADS; } // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // Every attention row is a distribution; equal keys give the mean of the values test multi_head_attention_basic_case - given query = default_input(), key = default_input(), value = default_input(), n_heads = DEFAULT_N_HEADS, d_model = DEFAULT_D_MODEL - when result = multi_head_attention(query, key, value, n_heads, d_model) - then result.output.len > 0 and result.attn_weights.len > 0 + given row_sum = attention_at(1, 0) + attention_at(1, 1) + attention_at(1, 2) + when tied = tie_attention(0) + then @abs(row_sum - 1.0) < 0.000001 and tied == 7.0 and tie_attention(1) == 7.0 and attention_at(0, 0) != 9.0 + // Heads are independent: head 1's weights (rows 9..17) differ from head 0's + test multi_head_attention_heads_differ + given w0 = attention_at(1, 1) + when w1 = attention_at(1, 10) + then w0 != w1 and w0 > 0.0 and w1 > 0.0 + + // W2 relu(W1 x + b1) + b2 on the fixture row, worked by hand: (0.4125, ..., -0.178125) test feed_forward_basic_case - given input = default_input(), d_model = DEFAULT_D_MODEL, d_ff = DEFAULT_D_FF, dropout = DEFAULT_DROPOUT - when result = feed_forward(input, d_model, d_ff, dropout) - then result.output.len > 0 + given y0 = ffn_at(0) + when y3 = ffn_at(3) + then @abs(y0 - 0.4125) < 0.000001 and @abs(y3 + 0.178125) < 0.000001 and @abs(ffn_at(2) + 0.928125) < 0.000001 + // Post-norm: every output row has mean 0 and variance 1 test forward_basic_case - given input = default_input(), config = EncoderBlockConfig { d_model = DEFAULT_D_MODEL, n_heads = DEFAULT_N_HEADS, d_ff = DEFAULT_D_FF, dropout = DEFAULT_DROPOUT, use_pre_norm = true } - when result = forward(input, config) - then result.output.len > 0 + given mean1 = block_at(false, 1, 1) + when var1 = block_at(false, 2, 1) + then @abs(mean1) < 0.00001 and @abs(var1 - 1.0) < 0.001 and @abs(block_at(false, 1, 2)) < 0.00001 + + // Pre-norm keeps the residual stream un-normalised, so it differs from post-norm + test forward_pre_norm_differs + given pre = block_at(true, 0, 0) + when post = block_at(false, 0, 0) + then pre != post and pre == pre // ═══════════════════════════════════════════════════════════ // TDD: Invariants (from .tri constraints) // ═══════════════════════════════════════════════════════════ + // d_model % n_heads == 0 invariant encoder_block_constraint_0 - given input = valid_input() - then true // d_model % n_heads == 0 + assert DEFAULT_D_MODEL % DEFAULT_N_HEADS == 0 and cfg(false).d_model % cfg(false).n_heads == 0 + // d_ff >= d_model invariant encoder_block_constraint_1 - given input = valid_input() - then true // d_ff >= d_model + assert DEFAULT_D_FF >= DEFAULT_D_MODEL and cfg(false).d_ff >= cfg(false).d_model + // name: encoder_block -- each head gets d_model / n_heads columns invariant encoder_block_constraint_2 - given input = valid_input() - then true // name: encoder_block + assert valid_input() == 64 + // "Vaswani et al. (2017) - Attention Is All You Need": dropout is a probability invariant encoder_block_constraint_3 - given input = valid_input() - then true // "Vaswani et al. (2017) - Attention Is All You Need" + assert DEFAULT_DROPOUT >= 0.0 and DEFAULT_DROPOUT < 1.0 + // "Baevski et al. (2020) - Revisiting the Self-Attention": both norm placements are offered invariant encoder_block_constraint_4 - given input = valid_input() - then true // "Baevski et al. (2020) - Revisiting the Self-Attention" - + assert cfg(true).use_pre_norm and !cfg(false).use_pre_norm diff --git a/apps/website/public/t27/files/specs/ml/transformer/positional_encoding.t27 b/apps/website/public/t27/files/specs/ml/transformer/positional_encoding.t27 index b1ca8a4650..11ed097e9a 100644 --- a/apps/website/public/t27/files/specs/ml/transformer/positional_encoding.t27 +++ b/apps/website/public/t27/files/specs/ml/transformer/positional_encoding.t27 @@ -2,6 +2,13 @@ // t27/specs/ // Uses sin/cos at different frequencies for each dimension | φ² + 1/φ² = 3 | TRINITY +// #8980: forward read an undeclared `d_model`, called `math::pow` / `math::sin` / +// `math::cos`, computed each encoding into a local and dropped it, and grew the +// frequency with the dimension where Vaswani et al. (2017) shrink it. It now +// writes the sinusoidal encoding +// PE(pos, 2i) = sin(pos / 10000^(2i / d)), PE(pos, 2i + 1) = cos(pos / 10000^(2i / d)) +// for each position into a positions x d_model buffer. + module PositionalEnc; use base::types; use math::constants; @@ -25,39 +32,57 @@ module PositionalEnc; // 3. Core Functions // ═══════════════════════════════════════════════════════════ - // forward(positions: []const u32) → void - fn forward(positions: []const u32) -> void { - // Compute positional encodings using sin/cos at different frequencies - // Each position gets a vector where even indices use sin and odd use cos - for (i in positions) { - // For each position, compute encodings for all dimensions - // Frequency increases by powers of 2: 1/10000, 1/10000^2, 1/10000^3, etc. - let freq_base = 1.0 / 10000.0; - for (dim in 0..d_model) { - let freq = freq_base * math::pow(2.0, cast(f64) dim / 2.0); + // 1 / 10000^(2i / d) = exp(-(2i / d) ln 10000) + fn inv_freq(pair: u32, d_model: u32) -> f32 { + return exp(-(@as(f32, @floatFromInt(2 * pair)) / @as(f32, @floatFromInt(d_model))) * log(@as(f32, 10000.0))); + } + + fn forward(positions: []const u32, config: PosEncConfig, out: []f32) -> void { + var p : usize = 0; + while (p < positions.len) { + const pos : f32 = @as(f32, @floatFromInt(positions[p])); + var dim : u32 = 0; + while (dim < config.d_model) { + const angle = pos * inv_freq(dim / 2, config.d_model); if (dim % 2 == 0) { - // Even dimensions: sin(pos / freq) - let encoding = math::sin(cast(f64) i * freq); + out[p * config.d_model + dim] = sin(angle); } else { - // Odd dimensions: cos(pos / freq) - let encoding = math::cos(cast(f64) i * freq); + out[p * config.d_model + dim] = cos(angle); } - // Store the encoding (implementation would typically store in an output array) + dim = dim + 1; } + p = p + 1; } } + // PE(pos, dim) for d_model 8 + fn pe(pos: u32, dim: usize) -> f32 { + const positions : [1]u32 = [pos]; + var out : [8]f32 = [9.0] ** 8; + forward(&positions, PosEncConfig{ .d_model = 8, .max_len = DEFAULT_MAX_LEN }, &out); + return out[dim]; + } + // ═══════════════════════════════════════════════════════════ // TDD: Tests (from .tri behaviors) // ═══════════════════════════════════════════════════════════ + // pos 1, d 8: dims 0/1 use frequency 1, dims 2/3 use 1/10 (10000^(2/8) = 10) test forward_basic_case - given input = default_input() - when result = forward(input) - then result != undefined + given s0 = pe(1, 0) + when s2 = pe(1, 2) + then @abs(s0 - 0.8414710) < 0.000001 and @abs(pe(1, 1) - 0.5403023) < 0.000001 and @abs(s2 - 0.0998334) < 0.000001 and @abs(pe(1, 3) - 0.9950042) < 0.000001 + // Position 0 encodes as (0, 1, 0, 1, ...) test forward_simple - given input = [0u32] - when result = forward(input) - then result != undefined + given s = pe(0, 6) + when c = pe(0, 7) + then s == 0.0 and c == 1.0 + + // Each sin/cos pair lies on the unit circle + test forward_pairs_are_unit_vectors + given p = pe(37, 2) * pe(37, 2) + pe(37, 3) * pe(37, 3) + then @abs(p - 1.0) < 0.000001 + invariant positional_encoding_max_len_is_positive + assert DEFAULT_MAX_LEN > 0 diff --git a/apps/website/public/widgets/gallery.t27 b/apps/website/public/widgets/gallery.t27 index 6285d9a4d1..17117ac2a9 100644 --- a/apps/website/public/widgets/gallery.t27 +++ b/apps/website/public/widgets/gallery.t27 @@ -78,15 +78,15 @@ pub const TOOL_NOSCRIPT : str = "This widget runs in your browser and needs Java ; Parallel arrays, WIDGET_COUNT long. WIDGET_TITLES is empty wherever the page carries an ; og:title, which is every kind but tab: the page is the one place the words live. A tool's ; WIDGET_HOOKS entry is empty too: its hook is the page's t27:hook, written from its own spec. -pub const WIDGET_COUNT : u8 = 252; -pub const WIDGET_IDS : [252]str = ["x7-board", "tri-x7-fasm", "tri-x7-mutate", "perf2-loop", "tri-fpga-rgmii", "tri-fpga-jtag", "tri-fpga-pins", "devkit-flow", "play-verilog", "bit-diff", "build-receipt", "cost-curves", "gf16-calc", "idcode", "lut-explain", "pin-map", "placement-map", "resource-bars", "slack-waterfall", "test-waves", "synth-smells", "bit-autopsy", "fasm-skyline", "vcd-wrapped", "fits-on", "stat-card", "lut-depth", "fsm-sketch", "lut-treemap", "t27-cell", "t27-vs-nvfp4", "uart-bucket", "tri-fpga-specs", "tri-fpga-tools", "tri-fpga-wire", "tri-fpga-batch", "tri-fpga-status", "tri-fpga-tmpcheck", "tri-fpga-keycheck", "tri-fpga-selftest", "tri-x7-refs", "tri-x7-audit", "t27c-clock-domain", "t27c-clocks", "t27c-wukong-v1", "t27c-cts", "t27c-mmcm", "t27c-mmcm-mutate", "t27c-timing", "t27c-reset-sync", "t27c-reset-sync-gen", "t27c-mtbf", "t27c-clock-domain-gen", "t27c-fifo", "t27c-fifo-mutate", "t27c-fifo-flags", "t27c-emitter-xdc", "t27c-fpga-rxcap", "t27-tri-competitors", "t27-tri-discard", "tri-fpga-txhold", "tri-fpga-rxcap", "tri-fpga-rxer", "tri-fpga-steps", "tri-fpga-ioclients", "tri-fpga-claim", "tri-fpga-release", "tri-fpga-next", "t27c-memory", "t27c-spi-tb", "t27c-check-uart", "t27c-check-spi", "t27c-check-apb", "t27c-check-axi4", "t27c-check-bridge", "t27c-check-memory", "t27c-verilog-uart", "t27c-verilog-spi", "t27c-verilog-apb", "t27c-verilog-axi4", "t27c-verilog-bridge", "t27c-verilog-top", "t27c-verilog-uart-tb", "t27c-verilog-apb-tb", "t27c-verilog-axi-tb", "t27c-verilog-mem-tb", "t27c-verilog-integration-tb", "t27c-verilog-top-tb", "t27c-verilog-spi-tb", "t27c-hir-uart", "t27c-hir-apb", "t27c-hir-axi4", "t27c-eth-crc", "t27c-rgmii", "jtag-verdict", "line-bounce", "eye-isi", "ecc-secded", "carry-chain", "prefix-adder", "csa-tree", "shift-add", "booth-radix4", "dsp-fit", "q-format", "round-sat", "sqnr", "cordic", "cordic-vector", "sine-table", "alias-fold", "nco", "dft-bin", "fir-response", "fir-design", "fir-cost", "decimator", "cic-growth", "polyphase", "fft-butterfly", "bit-reverse", "fft-scaling", "barker-corr", "fir-fit", "fir-on-board", "play-hello-world", "play-rust", "play-js", "t27c-hello-world", "t27-tri-misread", "test-touch", "t27c-stages", "t27c-e8m0", "play-e8m0", "t27c-ocp-mx", "play-gfternary", "t27c-gfternary", "play-golden-sieve", "t27c-golden-sieve", "play-tnf17", "t27c-tnf17", "t27c-activation-quantizer", "t27c-bitnet-majority", "t27c-bitnet-neuron-nchunk", "t27c-comb-ternary-dot", "t27c-stream-ternary-mac", "t27c-bitnet-mlp", "t27c-gft-smul", "t27c-gft-sadd", "t27c-gft-signed-mac", "t27c-gft-relu", "t27c-gft-exp2", "t27c-gft-argmax4", "t27c-gft-nll", "t27c-gft-sgd-step", "t27c-gft-xornet", "basics-what-a-spec-is", "basics-the-module-line", "basics-comments-and-prose", "basics-constants", "basics-whole-numbers", "basics-true-false-and-text", "basics-arrays", "basics-trits", "basics-expressions", "basics-a-test-block", "basics-many-tests", "basics-functions", "basics-local-names", "basics-if-and-else", "basics-loops", "basics-pub-or-private", "basics-structs", "basics-enums", "basics-use-other-modules", "basics-invariants", "basics-gen-ts", "basics-seven-backends", "basics-stages-of-t27c", "basics-tri-commands", "basics-reading-errors", "basics-a-small-program", "basics-where-next", "golden-split", "golden-phi-ratio", "golden-lucas", "golden-split-optimality", "golden-radix-economy", "golden-phi-in-gf16", "golden-gf4", "golden-gf6", "golden-gf8", "golden-gf10", "golden-gf12", "golden-gf14", "golden-gf16", "golden-dot-two", "golden-gf24", "golden-gf32", "golden-gf48", "golden-gf64", "golden-gf96", "golden-gf128", "golden-gf256", "golden-gf512", "golden-gf1024", "golden-gft8", "golden-gft16", "golden-gft32", "golden-decode", "t27-tri-vectors", "t27-tri-census", "t27-tri-seals", "t27-tri-prose", "t27-tri-lean", "tri-selftest", "play-terminal-gates", "tc-why-three", "tc-balanced-count", "tc-flip-and-cut", "tc-kleene-gates", "tc-consensus-any", "tc-sum-and-carry", "tc-half-adder", "tc-full-adder", "tc-ripple-carry", "tc-times-a-trit", "tc-long-multiply", "tc-ternary-mac", "tc-two-bits", "tc-five-in-a-byte", "tc-trit-word", "tc-instruction-word", "tc-opcode-map", "tc-immediate", "tc-ternary-alu", "tc-three-way-jump", "tc-run-a-program", "tc-compare", "tc-thirds", "tc-sort-three", "tc-one-neuron", "tc-detector", "tc-tiny-layer", "wars", "tri-game-tick", "tri-game-vault", "perf2-knockouts", "race-the-bee", "gatle", "tri-blog-list", "tri-game-selftest"]; -pub const WIDGET_KINDS : [252]str = ["cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "player", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "player", "player", "player", "cast", "cast", "tool", "tool", "cast", "player", "cast", "player", "cast", "player", "cast", "player", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tab", "cast", "cast", "cast", "tool", "tool", "cast", "cast"]; -pub const WIDGET_CATEGORIES : [252]str = ["fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "game", "game", "game", "game", "game", "game", "game", "game"]; -pub const WIDGET_PAGES : [252]str = ["term/x7-board/", "term/tri-x7-fasm/", "term/tri-x7-mutate/", "term/perf2-loop/", "term/tri-fpga-rgmii/", "term/tri-fpga-jtag/", "term/tri-fpga-pins/", "term/devkit-flow/", "play/hello-world/verilog/", "widgets/bit-diff/", "widgets/build-receipt/", "widgets/cost-curves/", "widgets/gf16-calc/", "widgets/idcode/", "widgets/lut-explain/", "widgets/pin-map/", "widgets/placement-map/", "widgets/resource-bars/", "widgets/slack-waterfall/", "widgets/test-waves/", "widgets/synth-smells/", "widgets/bit-autopsy/", "widgets/fasm-skyline/", "widgets/vcd-wrapped/", "widgets/fits-on/", "widgets/stat-card/", "widgets/lut-depth/", "widgets/fsm-sketch/", "widgets/lut-treemap/", "widgets/t27-cell/", "widgets/t27-vs-nvfp4/", "widgets/uart-bucket/", "term/tri-fpga-specs/", "term/tri-fpga-tools/", "term/tri-fpga-wire/", "term/tri-fpga-batch/", "term/tri-fpga-status/", "term/tri-fpga-tmpcheck/", "term/tri-fpga-keycheck/", "term/tri-fpga-selftest/", "term/tri-x7-refs/", "term/tri-x7-audit/", "term/t27c-clock-domain/", "term/t27c-clocks/", "term/t27c-wukong-v1/", "term/t27c-cts/", "term/t27c-mmcm/", "term/t27c-mmcm-mutate/", "term/t27c-timing/", "term/t27c-reset-sync/", "term/t27c-reset-sync-gen/", "term/t27c-mtbf/", "term/t27c-clock-domain-gen/", "term/t27c-fifo/", "term/t27c-fifo-mutate/", "term/t27c-fifo-flags/", "term/t27c-emitter-xdc/", "term/t27c-fpga-rxcap/", "term/t27-tri-competitors/", "term/t27-tri-discard/", "term/tri-fpga-txhold/", "term/tri-fpga-rxcap/", "term/tri-fpga-rxer/", "term/tri-fpga-steps/", "term/tri-fpga-ioclients/", "term/tri-fpga-claim/", "term/tri-fpga-release/", "term/tri-fpga-next/", "term/t27c-memory/", "term/t27c-spi-tb/", "term/t27c-check-uart/", "term/t27c-check-spi/", "term/t27c-check-apb/", "term/t27c-check-axi4/", "term/t27c-check-bridge/", "term/t27c-check-memory/", "term/t27c-verilog-uart/", "term/t27c-verilog-spi/", "term/t27c-verilog-apb/", "term/t27c-verilog-axi4/", "term/t27c-verilog-bridge/", "term/t27c-verilog-top/", "term/t27c-verilog-uart-tb/", "term/t27c-verilog-apb-tb/", "term/t27c-verilog-axi-tb/", "term/t27c-verilog-mem-tb/", "term/t27c-verilog-integration-tb/", "term/t27c-verilog-top-tb/", "term/t27c-verilog-spi-tb/", "term/t27c-hir-uart/", "term/t27c-hir-apb/", "term/t27c-hir-axi4/", "term/t27c-eth-crc/", "term/t27c-rgmii/", "widgets/jtag-verdict/", "widgets/line-bounce/", "widgets/eye-isi/", "widgets/ecc-secded/", "widgets/carry-chain/", "widgets/prefix-adder/", "widgets/csa-tree/", "widgets/shift-add/", "widgets/booth-radix4/", "widgets/dsp-fit/", "widgets/q-format/", "widgets/round-sat/", "widgets/sqnr/", "widgets/cordic/", "widgets/cordic-vector/", "widgets/sine-table/", "widgets/alias-fold/", "widgets/nco/", "widgets/dft-bin/", "widgets/fir-response/", "widgets/fir-design/", "widgets/fir-cost/", "widgets/decimator/", "widgets/cic-growth/", "widgets/polyphase/", "widgets/fft-butterfly/", "widgets/bit-reverse/", "widgets/fft-scaling/", "widgets/barker-corr/", "widgets/fir-fit/", "widgets/fir-on-board/", "play/hello-world/", "play/hello-world/rust/", "play/hello-world/js/", "term/t27c-hello-world/", "term/t27-tri-misread/", "widgets/test-touch/", "widgets/t27c-stages/", "term/t27c-e8m0/", "play/e8m0/", "term/t27c-ocp-mx/", "play/gfternary/", "term/t27c-gfternary/", "play/golden-sieve/", "term/t27c-golden-sieve/", "play/tnf17/", "term/t27c-tnf17/", "term/t27c-activation-quantizer/", "term/t27c-bitnet-majority/", "term/t27c-bitnet-neuron-nchunk/", "term/t27c-comb-ternary-dot/", "term/t27c-stream-ternary-mac/", "term/t27c-bitnet-mlp/", "term/t27c-gft-smul/", "term/t27c-gft-sadd/", "term/t27c-gft-signed-mac/", "term/t27c-gft-relu/", "term/t27c-gft-exp2/", "term/t27c-gft-argmax4/", "term/t27c-gft-nll/", "term/t27c-gft-sgd-step/", "term/t27c-gft-xornet/", "widgets/basics-what-a-spec-is/", "widgets/basics-the-module-line/", "widgets/basics-comments-and-prose/", "widgets/basics-constants/", "widgets/basics-whole-numbers/", "widgets/basics-true-false-and-text/", "widgets/basics-arrays/", "widgets/basics-trits/", "widgets/basics-expressions/", "widgets/basics-a-test-block/", "widgets/basics-many-tests/", "widgets/basics-functions/", "widgets/basics-local-names/", "widgets/basics-if-and-else/", "widgets/basics-loops/", "widgets/basics-pub-or-private/", "widgets/basics-structs/", "widgets/basics-enums/", "widgets/basics-use-other-modules/", "widgets/basics-invariants/", "widgets/basics-gen-ts/", "widgets/basics-seven-backends/", "widgets/basics-stages-of-t27c/", "widgets/basics-tri-commands/", "widgets/basics-reading-errors/", "widgets/basics-a-small-program/", "widgets/basics-where-next/", "widgets/golden-split/", "widgets/golden-phi-ratio/", "widgets/golden-lucas/", "widgets/golden-split-optimality/", "widgets/golden-radix-economy/", "widgets/golden-phi-in-gf16/", "widgets/golden-gf4/", "widgets/golden-gf6/", "widgets/golden-gf8/", "widgets/golden-gf10/", "widgets/golden-gf12/", "widgets/golden-gf14/", "widgets/golden-gf16/", "widgets/golden-dot-two/", "widgets/golden-gf24/", "widgets/golden-gf32/", "widgets/golden-gf48/", "widgets/golden-gf64/", "widgets/golden-gf96/", "widgets/golden-gf128/", "widgets/golden-gf256/", "widgets/golden-gf512/", "widgets/golden-gf1024/", "widgets/golden-gft8/", "widgets/golden-gft16/", "widgets/golden-gft32/", "widgets/golden-decode/", "term/t27-tri-vectors/", "term/t27-tri-census/", "term/t27-tri-seals/", "term/t27-tri-prose/", "term/t27-tri-lean/", "term/tri-selftest/", "term/play-terminal-gates/", "widgets/tc-why-three/", "widgets/tc-balanced-count/", "widgets/tc-flip-and-cut/", "widgets/tc-kleene-gates/", "widgets/tc-consensus-any/", "widgets/tc-sum-and-carry/", "widgets/tc-half-adder/", "widgets/tc-full-adder/", "widgets/tc-ripple-carry/", "widgets/tc-times-a-trit/", "widgets/tc-long-multiply/", "widgets/tc-ternary-mac/", "widgets/tc-two-bits/", "widgets/tc-five-in-a-byte/", "widgets/tc-trit-word/", "widgets/tc-instruction-word/", "widgets/tc-opcode-map/", "widgets/tc-immediate/", "widgets/tc-ternary-alu/", "widgets/tc-three-way-jump/", "widgets/tc-run-a-program/", "widgets/tc-compare/", "widgets/tc-thirds/", "widgets/tc-sort-three/", "widgets/tc-one-neuron/", "widgets/tc-detector/", "widgets/tc-tiny-layer/", "wars", "term/tri-game-tick/", "term/tri-game-vault/", "term/perf2-knockouts/", "widgets/race-the-bee/", "widgets/gatle/", "term/tri-blog-list/", "term/tri-game-selftest/"]; -pub const WIDGET_TITLES : [252]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "WARS: agent configurations compared on real GitHub issues", "", "", "", "", "", "", ""]; -pub const WIDGET_LINES : [252]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "One issue, one pinned commit, the same tools and gates; only the decision layer changes, and a missing run stays unknown.", "", "", "", "", "", "", ""]; +pub const WIDGET_COUNT : u16 = 279; +pub const WIDGET_IDS : [279]str = ["x7-board", "tri-x7-fasm", "tri-x7-mutate", "perf2-loop", "tri-fpga-rgmii", "tri-fpga-jtag", "tri-fpga-pins", "devkit-flow", "play-verilog", "bit-diff", "build-receipt", "cost-curves", "gf16-calc", "idcode", "lut-explain", "pin-map", "placement-map", "resource-bars", "slack-waterfall", "test-waves", "synth-smells", "bit-autopsy", "fasm-skyline", "vcd-wrapped", "fits-on", "stat-card", "lut-depth", "fsm-sketch", "lut-treemap", "t27-cell", "t27-vs-nvfp4", "uart-bucket", "tri-fpga-specs", "tri-fpga-tools", "tri-fpga-wire", "tri-fpga-batch", "tri-fpga-status", "tri-fpga-tmpcheck", "tri-fpga-keycheck", "tri-fpga-selftest", "tri-x7-refs", "tri-x7-audit", "t27c-clock-domain", "t27c-clocks", "t27c-wukong-v1", "t27c-cts", "t27c-mmcm", "t27c-mmcm-mutate", "t27c-timing", "t27c-reset-sync", "t27c-reset-sync-gen", "t27c-mtbf", "t27c-clock-domain-gen", "t27c-fifo", "t27c-fifo-mutate", "t27c-fifo-flags", "t27c-emitter-xdc", "t27c-fpga-rxcap", "t27-tri-competitors", "t27-tri-discard", "tri-fpga-txhold", "tri-fpga-rxcap", "tri-fpga-rxer", "tri-fpga-steps", "tri-fpga-ioclients", "tri-fpga-claim", "tri-fpga-release", "tri-fpga-next", "t27c-memory", "t27c-spi-tb", "t27c-check-uart", "t27c-check-spi", "t27c-check-apb", "t27c-check-axi4", "t27c-check-bridge", "t27c-check-memory", "t27c-verilog-uart", "t27c-verilog-spi", "t27c-verilog-apb", "t27c-verilog-axi4", "t27c-verilog-bridge", "t27c-verilog-top", "t27c-verilog-uart-tb", "t27c-verilog-apb-tb", "t27c-verilog-axi-tb", "t27c-verilog-mem-tb", "t27c-verilog-integration-tb", "t27c-verilog-top-tb", "t27c-verilog-spi-tb", "t27c-hir-uart", "t27c-hir-apb", "t27c-hir-axi4", "t27c-eth-crc", "t27c-rgmii", "jtag-verdict", "line-bounce", "eye-isi", "ecc-secded", "carry-chain", "prefix-adder", "csa-tree", "shift-add", "booth-radix4", "dsp-fit", "q-format", "round-sat", "sqnr", "cordic", "cordic-vector", "sine-table", "alias-fold", "nco", "dft-bin", "fir-response", "fir-design", "fir-cost", "decimator", "cic-growth", "polyphase", "fft-butterfly", "bit-reverse", "fft-scaling", "barker-corr", "fir-fit", "fir-on-board", "play-hello-world", "play-rust", "play-js", "t27c-hello-world", "t27-tri-misread", "test-touch", "t27c-stages", "t27c-e8m0", "play-e8m0", "t27c-ocp-mx", "play-gfternary", "t27c-gfternary", "play-golden-sieve", "t27c-golden-sieve", "play-tnf17", "t27c-tnf17", "t27c-activation-quantizer", "t27c-bitnet-majority", "t27c-bitnet-neuron-nchunk", "t27c-comb-ternary-dot", "t27c-stream-ternary-mac", "t27c-bitnet-mlp", "t27c-gft-smul", "t27c-gft-sadd", "t27c-gft-signed-mac", "t27c-gft-relu", "t27c-gft-exp2", "t27c-gft-argmax4", "t27c-gft-nll", "t27c-gft-sgd-step", "t27c-gft-xornet", "basics-what-a-spec-is", "basics-the-module-line", "basics-comments-and-prose", "basics-constants", "basics-whole-numbers", "basics-true-false-and-text", "basics-arrays", "basics-trits", "basics-expressions", "basics-a-test-block", "basics-many-tests", "basics-functions", "basics-local-names", "basics-if-and-else", "basics-loops", "basics-pub-or-private", "basics-structs", "basics-enums", "basics-use-other-modules", "basics-invariants", "basics-gen-ts", "basics-seven-backends", "basics-stages-of-t27c", "basics-tri-commands", "basics-reading-errors", "basics-a-small-program", "basics-where-next", "golden-split", "golden-phi-ratio", "golden-lucas", "golden-split-optimality", "golden-radix-economy", "golden-phi-in-gf16", "golden-gf4", "golden-gf6", "golden-gf8", "golden-gf10", "golden-gf12", "golden-gf14", "golden-gf16", "golden-dot-two", "golden-gf24", "golden-gf32", "golden-gf48", "golden-gf64", "golden-gf96", "golden-gf128", "golden-gf256", "golden-gf512", "golden-gf1024", "golden-gft8", "golden-gft16", "golden-gft32", "golden-decode", "t27-tri-vectors", "t27-tri-census", "t27-tri-seals", "t27-tri-prose", "t27-tri-lean", "tri-selftest", "play-terminal-gates", "tc-why-three", "tc-balanced-count", "tc-flip-and-cut", "tc-kleene-gates", "tc-consensus-any", "tc-sum-and-carry", "tc-half-adder", "tc-full-adder", "tc-ripple-carry", "tc-times-a-trit", "tc-long-multiply", "tc-ternary-mac", "tc-two-bits", "tc-five-in-a-byte", "tc-trit-word", "tc-instruction-word", "tc-opcode-map", "tc-immediate", "tc-ternary-alu", "tc-three-way-jump", "tc-run-a-program", "tc-compare", "tc-thirds", "tc-sort-three", "tc-one-neuron", "tc-detector", "tc-tiny-layer", "nn-relu", "nn-sigmoid", "nn-tanh", "nn-gelu", "nn-silu", "nn-elu", "nn-softmax", "nn-embedding", "nn-dropout", "nn-conv", "nn-maxpool", "nn-batchnorm", "nn-mse", "nn-bce", "nn-huber", "nn-sgd", "nn-rmsprop", "nn-adam", "nn-backprop", "nn-xor", "nn-lamb", "nn-rnn", "nn-lstm", "nn-attention", "nn-positions", "nn-encoder", "nn-ppo", "wars", "tri-game-tick", "tri-game-vault", "perf2-knockouts", "race-the-bee", "gatle", "tri-blog-list", "tri-game-selftest"]; +pub const WIDGET_KINDS : [279]str = ["cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "player", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "player", "player", "player", "cast", "cast", "tool", "tool", "cast", "player", "cast", "player", "cast", "player", "cast", "player", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tab", "cast", "cast", "cast", "tool", "tool", "cast", "cast"]; +pub const WIDGET_CATEGORIES : [279]str = ["fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "game", "game", "game", "game", "game", "game", "game", "game"]; +pub const WIDGET_PAGES : [279]str = ["term/x7-board/", "term/tri-x7-fasm/", "term/tri-x7-mutate/", "term/perf2-loop/", "term/tri-fpga-rgmii/", "term/tri-fpga-jtag/", "term/tri-fpga-pins/", "term/devkit-flow/", "play/hello-world/verilog/", "widgets/bit-diff/", "widgets/build-receipt/", "widgets/cost-curves/", "widgets/gf16-calc/", "widgets/idcode/", "widgets/lut-explain/", "widgets/pin-map/", "widgets/placement-map/", "widgets/resource-bars/", "widgets/slack-waterfall/", "widgets/test-waves/", "widgets/synth-smells/", "widgets/bit-autopsy/", "widgets/fasm-skyline/", "widgets/vcd-wrapped/", "widgets/fits-on/", "widgets/stat-card/", "widgets/lut-depth/", "widgets/fsm-sketch/", "widgets/lut-treemap/", "widgets/t27-cell/", "widgets/t27-vs-nvfp4/", "widgets/uart-bucket/", "term/tri-fpga-specs/", "term/tri-fpga-tools/", "term/tri-fpga-wire/", "term/tri-fpga-batch/", "term/tri-fpga-status/", "term/tri-fpga-tmpcheck/", "term/tri-fpga-keycheck/", "term/tri-fpga-selftest/", "term/tri-x7-refs/", "term/tri-x7-audit/", "term/t27c-clock-domain/", "term/t27c-clocks/", "term/t27c-wukong-v1/", "term/t27c-cts/", "term/t27c-mmcm/", "term/t27c-mmcm-mutate/", "term/t27c-timing/", "term/t27c-reset-sync/", "term/t27c-reset-sync-gen/", "term/t27c-mtbf/", "term/t27c-clock-domain-gen/", "term/t27c-fifo/", "term/t27c-fifo-mutate/", "term/t27c-fifo-flags/", "term/t27c-emitter-xdc/", "term/t27c-fpga-rxcap/", "term/t27-tri-competitors/", "term/t27-tri-discard/", "term/tri-fpga-txhold/", "term/tri-fpga-rxcap/", "term/tri-fpga-rxer/", "term/tri-fpga-steps/", "term/tri-fpga-ioclients/", "term/tri-fpga-claim/", "term/tri-fpga-release/", "term/tri-fpga-next/", "term/t27c-memory/", "term/t27c-spi-tb/", "term/t27c-check-uart/", "term/t27c-check-spi/", "term/t27c-check-apb/", "term/t27c-check-axi4/", "term/t27c-check-bridge/", "term/t27c-check-memory/", "term/t27c-verilog-uart/", "term/t27c-verilog-spi/", "term/t27c-verilog-apb/", "term/t27c-verilog-axi4/", "term/t27c-verilog-bridge/", "term/t27c-verilog-top/", "term/t27c-verilog-uart-tb/", "term/t27c-verilog-apb-tb/", "term/t27c-verilog-axi-tb/", "term/t27c-verilog-mem-tb/", "term/t27c-verilog-integration-tb/", "term/t27c-verilog-top-tb/", "term/t27c-verilog-spi-tb/", "term/t27c-hir-uart/", "term/t27c-hir-apb/", "term/t27c-hir-axi4/", "term/t27c-eth-crc/", "term/t27c-rgmii/", "widgets/jtag-verdict/", "widgets/line-bounce/", "widgets/eye-isi/", "widgets/ecc-secded/", "widgets/carry-chain/", "widgets/prefix-adder/", "widgets/csa-tree/", "widgets/shift-add/", "widgets/booth-radix4/", "widgets/dsp-fit/", "widgets/q-format/", "widgets/round-sat/", "widgets/sqnr/", "widgets/cordic/", "widgets/cordic-vector/", "widgets/sine-table/", "widgets/alias-fold/", "widgets/nco/", "widgets/dft-bin/", "widgets/fir-response/", "widgets/fir-design/", "widgets/fir-cost/", "widgets/decimator/", "widgets/cic-growth/", "widgets/polyphase/", "widgets/fft-butterfly/", "widgets/bit-reverse/", "widgets/fft-scaling/", "widgets/barker-corr/", "widgets/fir-fit/", "widgets/fir-on-board/", "play/hello-world/", "play/hello-world/rust/", "play/hello-world/js/", "term/t27c-hello-world/", "term/t27-tri-misread/", "widgets/test-touch/", "widgets/t27c-stages/", "term/t27c-e8m0/", "play/e8m0/", "term/t27c-ocp-mx/", "play/gfternary/", "term/t27c-gfternary/", "play/golden-sieve/", "term/t27c-golden-sieve/", "play/tnf17/", "term/t27c-tnf17/", "term/t27c-activation-quantizer/", "term/t27c-bitnet-majority/", "term/t27c-bitnet-neuron-nchunk/", "term/t27c-comb-ternary-dot/", "term/t27c-stream-ternary-mac/", "term/t27c-bitnet-mlp/", "term/t27c-gft-smul/", "term/t27c-gft-sadd/", "term/t27c-gft-signed-mac/", "term/t27c-gft-relu/", "term/t27c-gft-exp2/", "term/t27c-gft-argmax4/", "term/t27c-gft-nll/", "term/t27c-gft-sgd-step/", "term/t27c-gft-xornet/", "widgets/basics-what-a-spec-is/", "widgets/basics-the-module-line/", "widgets/basics-comments-and-prose/", "widgets/basics-constants/", "widgets/basics-whole-numbers/", "widgets/basics-true-false-and-text/", "widgets/basics-arrays/", "widgets/basics-trits/", "widgets/basics-expressions/", "widgets/basics-a-test-block/", "widgets/basics-many-tests/", "widgets/basics-functions/", "widgets/basics-local-names/", "widgets/basics-if-and-else/", "widgets/basics-loops/", "widgets/basics-pub-or-private/", "widgets/basics-structs/", "widgets/basics-enums/", "widgets/basics-use-other-modules/", "widgets/basics-invariants/", "widgets/basics-gen-ts/", "widgets/basics-seven-backends/", "widgets/basics-stages-of-t27c/", "widgets/basics-tri-commands/", "widgets/basics-reading-errors/", "widgets/basics-a-small-program/", "widgets/basics-where-next/", "widgets/golden-split/", "widgets/golden-phi-ratio/", "widgets/golden-lucas/", "widgets/golden-split-optimality/", "widgets/golden-radix-economy/", "widgets/golden-phi-in-gf16/", "widgets/golden-gf4/", "widgets/golden-gf6/", "widgets/golden-gf8/", "widgets/golden-gf10/", "widgets/golden-gf12/", "widgets/golden-gf14/", "widgets/golden-gf16/", "widgets/golden-dot-two/", "widgets/golden-gf24/", "widgets/golden-gf32/", "widgets/golden-gf48/", "widgets/golden-gf64/", "widgets/golden-gf96/", "widgets/golden-gf128/", "widgets/golden-gf256/", "widgets/golden-gf512/", "widgets/golden-gf1024/", "widgets/golden-gft8/", "widgets/golden-gft16/", "widgets/golden-gft32/", "widgets/golden-decode/", "term/t27-tri-vectors/", "term/t27-tri-census/", "term/t27-tri-seals/", "term/t27-tri-prose/", "term/t27-tri-lean/", "term/tri-selftest/", "term/play-terminal-gates/", "widgets/tc-why-three/", "widgets/tc-balanced-count/", "widgets/tc-flip-and-cut/", "widgets/tc-kleene-gates/", "widgets/tc-consensus-any/", "widgets/tc-sum-and-carry/", "widgets/tc-half-adder/", "widgets/tc-full-adder/", "widgets/tc-ripple-carry/", "widgets/tc-times-a-trit/", "widgets/tc-long-multiply/", "widgets/tc-ternary-mac/", "widgets/tc-two-bits/", "widgets/tc-five-in-a-byte/", "widgets/tc-trit-word/", "widgets/tc-instruction-word/", "widgets/tc-opcode-map/", "widgets/tc-immediate/", "widgets/tc-ternary-alu/", "widgets/tc-three-way-jump/", "widgets/tc-run-a-program/", "widgets/tc-compare/", "widgets/tc-thirds/", "widgets/tc-sort-three/", "widgets/tc-one-neuron/", "widgets/tc-detector/", "widgets/tc-tiny-layer/", "widgets/nn-relu/", "widgets/nn-sigmoid/", "widgets/nn-tanh/", "widgets/nn-gelu/", "widgets/nn-silu/", "widgets/nn-elu/", "widgets/nn-softmax/", "widgets/nn-embedding/", "widgets/nn-dropout/", "widgets/nn-conv/", "widgets/nn-maxpool/", "widgets/nn-batchnorm/", "widgets/nn-mse/", "widgets/nn-bce/", "widgets/nn-huber/", "widgets/nn-sgd/", "widgets/nn-rmsprop/", "widgets/nn-adam/", "widgets/nn-backprop/", "widgets/nn-xor/", "widgets/nn-lamb/", "widgets/nn-rnn/", "widgets/nn-lstm/", "widgets/nn-attention/", "widgets/nn-positions/", "widgets/nn-encoder/", "widgets/nn-ppo/", "wars", "term/tri-game-tick/", "term/tri-game-vault/", "term/perf2-knockouts/", "widgets/race-the-bee/", "widgets/gatle/", "term/tri-blog-list/", "term/tri-game-selftest/"]; +pub const WIDGET_TITLES : [279]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "WARS: agent configurations compared on real GitHub issues", "", "", "", "", "", "", ""]; +pub const WIDGET_LINES : [279]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "One issue, one pinned commit, the same tools and gates; only the decision layer changes, and a missing run stays unknown.", "", "", "", "", "", "", ""]; ; Why a person would pass this one on: the reason the widget is in the gallery at all. -pub const WIDGET_HOOKS : [252]str = ["The bitstream is byte-identical to openXC7's and runs on a real board: the claim most FPGA people doubt, shown.", "A Xilinx 7-series bitstream assembled with no Vivado anywhere in the path.", "Plant a bug in the bitstream path and watch the tests catch it: mutation testing for hardware.", "Place and route to a loaded bitstream, with the clock on screen.", "RGMII hold margins read from nextpnr's own SDF, not from a datasheet.", "The cable asks which chip is there and the chip answers with its IDCODE.", "Before an edit to a Verilog file: every spec and generator it would touch.", "The whole FPGA flow, one layer per line, from spec to board.", "A spec turned into Verilog inside a post, with the RTL read the way a hardware engineer reads it.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "17 of 17 conformance specs compile, their test blocks pass, and no generated file has drifted.", "14 of 14 bench tools pass their own self-tests in one sweep: decode 18/18, repin 17/17, firelog 10/10, tmpcheck 9/9, stamps 9/9, keep 9/9.", "Requested 115,200 puts 115,385 on the wire (+0.16 %), 921,600 puts 923,077, and 3,000,000 is exact.", "26 checks, no board, no RTL: every receipt returns, 11 loss and fault cases recover, and a lie stops the run.", "One command reads the bench: cables, locks, and the last board runs: three x7-board runs PASS 51840/51840.", "112 files under /tmp pinned by sha256 in specs: every one has a kept copy, 0 lost, 0 unlocated.", "84 board and model logs scanned for the TRI-NET key: 0 hits, 0 logs of 1 MB or more.", "16 spec-named scripts run their own --self-test, 0 bad; 8 without the flag are listed, not skipped silently.", "The part table in far.t27 matches prjxray-db part.json, all 6 reference bitstreams present, bitwalk reads all 6 in 84.4 ms.", "One command re-runs every sweep: CRC 12/12, ECC 32520/32520 frames, 82/82 pins, 4224/4224 segbits, gold 5/5. audit: CLEAN.", "The CDC spec through the real compiler: 12 tests pass natively and the header says what the model does and does not claim.", "The tri clocks card as a spec: constants a tool page reads, and a native test-report that says so plainly -- 0 tests, because it is not a test suite.", "The board itself as a spec: 15 tests pass natively and the part line names the xc7a200tfgg676 the Wukong carries.", "Clock-tree synthesis in numbers: 15 tests pass natively, and the header pins the Artix-7 teaching delays the tree arithmetic uses.", "The MMCM model through the real compiler: VCO window, M/D/O ranges, fractional multiply in eighths, the 1/56 phase step, 16 tests natively.", "Widen the VCO window with one sed and exactly one test objects -- the rejection test that names the 500 MHz config it calls out.", "Static timing as arithmetic: 25 tests pass natively on arcs, slack and Fmax, with the Artix-7 teaching delays in the header.", "The three reset kinds through the real compiler: async assert with sync release through 2 to 4 flops, and the racy async release, 16 tests natively.", "What the compiler emits for the reset pipe: t27c gen prints the Zig, one struct copy per clock, and wc -l counts it.", "Metastability MTBF without floats: the WP323 form in Q10 log2, one flop negative slack, two flops astronomical, 15 tests natively.", "The CDC model as Zig: t27c gen prints what it compiled and wc -l says how many lines of code the model is.", "The FIFO stdlib through the real compiler: 18 tests pass natively and 6 invariants are proved comptime.", "Move a pointer by 3 instead of 1 and every test still passes: the suite asserts fill and flags, never pointer values.", "Flip one flag assignment and a single test objects: the guard that keeps the FIFO honest.", "The pins-to-XDC emitter spec parsed by the real compiler, and the create_clock lines it exists to write.", "The fpga-rxcap tool card as a spec: constants for a tool page, and a native run that says 0 tests and why.", "168 records: 14 papers entered twice, 141 cite no score, 144 state zero at pass@1.", "67 specs lose 23,578 tokens to parser recovery, each held at its pinned bound.", "Smallest hold 3445 ps on TXD1 against a 1000 ps bench; each TX pin setup and hold from the routed SDF.", "Per-bit setup and hold of an async RX nibble against its RXC edge, from the routed SDF: one nibble changes 2387 to 2486 ps apart, so a binary counter tears where a gray one cannot.", "RX_ER pulses injected at exact nibble positions of a ping -- preamble, mid-frame, IP header -- and the frame state each pulse leaves behind, RTL vs model.", "The Ethernet bring-up plan on the bench: pre-registered steps, logged exits, what ran and what did not.", "The registered IO clients on the bench, read live: names, claims and what each declares it owns.", "The bench claim in action: one client takes the hardware lock and the tool reports who holds it.", "The bench lock given back: the client gives up its claim and the bench reports itself free.", "The next queued step on the bench, read live from the run state.", "The memory map spec through the real compiler: 15 tests pass natively and 6 invariants are proved comptime.", "The SPI testbench through the real compiler: 7 tests pass natively, driving the modes and checking the captures.", "t27c check on the UART spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the SPI spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the APB bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the AXI4 spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the bus bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the memory spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "The UART spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The SPI spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The APB bridge spec lowered to synthesizable Verilog: port list, PSEL and PENABLE wiring, the address decode.", "The AXI4 spec lowered to synthesizable Verilog: the five channels' wiring and handshakes as generated wires.", "The bus bridge spec lowered to synthesizable Verilog: both sides of the crossing as generated wires.", "The whole design in one spec lowered to synthesizable Verilog: clocks, resets and bus wiring as the compiler emits them.", "The UART testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The APB bridge testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The AXI4 testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The memory testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The integration testbench spec lowered to Verilog: every bus of the design in one bench.", "The top-level testbench spec lowered to Verilog: the whole design under one bench.", "The SPI testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The UART spec lowered to hardware IR: the compiler's own view of the wires and state before Verilog exists.", "The APB bridge spec lowered to hardware IR: PSEL, PENABLE and the decode as the compiler structures them.", "The AXI4 spec lowered to hardware IR: the five channels and their handshakes as the compiler structures them.", "The Ethernet FCS spec through the real compiler: 8 tests pass natively -- the table derived from one bit step, the 0xCBF43926 check value, the 0xDEBB20E3 receiver residue.", "The RGMII spec through the real compiler: 7 tests pass natively and 1 invariant is proved comptime -- the 8 ns gigabit period, a nibble on both edges, the 78 ps tap ladder.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "The t27 compiler running as WebAssembly in a post: compile, test, seven backends.", "The same spec as Rust, printed by a terminal in the page.", "The only backend that runs in the browser: generate the module, then run it.", "t27c on hello_world.t27, on a real machine, every byte as printed.", "Code that compiles and is wrong: the tool that finds it.", "", "", "The OCP MX scale byte as a spec: 2^(e-127), code 255 is NaN, 18 tests and 9 comptime invariants, compiled on a real machine.", "The same scale byte compiled in your browser: seven backends, the spec's tests run in the page, and every skip says why.", "One outlier sets the scale for 32 weights: MXFP4 flushes 23 of them to zero, MXFP8 E4M3 none. 49 tests pass; a planted bug fails one.", "Ternary weights scaled by phi, compiled in your browser: codes 00, 01, 10, and the fourth code folded to zero.", "13 of 13 tests pass natively, and the report says 8 of them executed no assert; a planted bug fails exactly one.", "Five measured rules for a ternary weight alphabet, and the one formula that passes all five, run in your browser.", "One more trit and the spec does not compile at all: BLOCKED, not failed, because no test ever ran.", "A 17-bit float whose exponent is four balanced trits, 3^4 = 81 values, compiled in your browser.", "34 tests pass natively, none vacuous; swap one XOR for OR and only the test that negates twice fails.", "A neuron's sum squeezed back to one trit: 7 tests pass natively, and turning one > into >= fails only the boundary test.", "One ternary neuron, two functions picked by its weights: 12 tests pass natively, and one weight moved from P to Z fails exactly one.", "A neuron wider than 27 inputs, summed chunk by chunk: 11 tests pass natively, and a loop that stops after one chunk fails exactly one.", "A 27-lane ternary dot product as pure wires: 4 tests pass natively, and one wrong sign in tmul fails exactly one.", "The same dot product added into a register on every clock: 4 tests pass natively, and a lane mask short one bit fails exactly one.", "A whole small ternary network, 3 neurons then 2: 4 tests pass natively, and a trit packed one bit low fails exactly one.", "A signed multiply: 3 tests pass natively, none vacuous, and a sign stuck at 0 fails exactly one, m2.", "A signed add: 3 tests pass natively, and adding where opposite signs must subtract fails exactly one, a2.", "Two signed products summed: 4 tests pass natively, and OR in place of the sign XOR fails exactly one, pp.", "A ReLU: 4 tests pass natively, and letting negative inputs through fails only negz, the one test with a negative input.", "2^x for a softmax: 4 tests pass natively, and dropping the minus sign of k fails exactly one, em1.", "argmax by comparing bits alone: 4 tests pass natively, and >= in place of > fails exactly one, tie_low.", "A loss in bits: 3 tests pass natively, and a zero with the sign bit set fails exactly one, perfect.", "One SGD step: 3 tests pass natively, and g times g in place of eta times g fails exactly one, ascend.", "A 2-layer ReLU net for XOR: 4 tests pass natively, and one relu removed fails exactly one, x00.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "34 vector files, 512 cases: 2 files executed, 8 debt, 24 prose-only; 19% carry data.", "Four census populations recounted another way all agree; three are named as uncheckable.", "31 of 1,428 seals record no output (16 specs); 3 of those are missing from the debt ledger.", "11 specs refused at parse, 0 blocked only by prose, 23 broken on purpose as fixtures.", "12 Lean files, 15,553 lines and 4 sorry, are reached by no build root: nothing compiles them.", "tri, railway, python3 and the loop directory: each present or not, in one call.", "The terminal for seven t27 backends: every command run on hello_world. 21 pass, 0 fail.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Pick a lane and see whether the TRI decision layer beats the baseline on the same issue.", "One tick of the Queen's loop: an anomaly scan that reports only what changed.", "The loop's skills checked against snapshots before an agent may use them.", "Three performance bits, and one knockout bitstream per bit to prove each one matters.", "", "", "73 published posts with date, language and revision, newest first.", "6 of 6 self-tests hold: anomalies, blog_drift, lessons, site_gate, tick, vault."]; +pub const WIDGET_HOOKS : [279]str = ["The bitstream is byte-identical to openXC7's and runs on a real board: the claim most FPGA people doubt, shown.", "A Xilinx 7-series bitstream assembled with no Vivado anywhere in the path.", "Plant a bug in the bitstream path and watch the tests catch it: mutation testing for hardware.", "Place and route to a loaded bitstream, with the clock on screen.", "RGMII hold margins read from nextpnr's own SDF, not from a datasheet.", "The cable asks which chip is there and the chip answers with its IDCODE.", "Before an edit to a Verilog file: every spec and generator it would touch.", "The whole FPGA flow, one layer per line, from spec to board.", "A spec turned into Verilog inside a post, with the RTL read the way a hardware engineer reads it.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "17 of 17 conformance specs compile, their test blocks pass, and no generated file has drifted.", "14 of 14 bench tools pass their own self-tests in one sweep: decode 18/18, repin 17/17, firelog 10/10, tmpcheck 9/9, stamps 9/9, keep 9/9.", "Requested 115,200 puts 115,385 on the wire (+0.16 %), 921,600 puts 923,077, and 3,000,000 is exact.", "26 checks, no board, no RTL: every receipt returns, 11 loss and fault cases recover, and a lie stops the run.", "One command reads the bench: cables, locks, and the last board runs: three x7-board runs PASS 51840/51840.", "112 files under /tmp pinned by sha256 in specs: every one has a kept copy, 0 lost, 0 unlocated.", "84 board and model logs scanned for the TRI-NET key: 0 hits, 0 logs of 1 MB or more.", "16 spec-named scripts run their own --self-test, 0 bad; 8 without the flag are listed, not skipped silently.", "The part table in far.t27 matches prjxray-db part.json, all 6 reference bitstreams present, bitwalk reads all 6 in 84.4 ms.", "One command re-runs every sweep: CRC 12/12, ECC 32520/32520 frames, 82/82 pins, 4224/4224 segbits, gold 5/5. audit: CLEAN.", "The CDC spec through the real compiler: 12 tests pass natively and the header says what the model does and does not claim.", "The tri clocks card as a spec: constants a tool page reads, and a native test-report that says so plainly -- 0 tests, because it is not a test suite.", "The board itself as a spec: 15 tests pass natively and the part line names the xc7a200tfgg676 the Wukong carries.", "Clock-tree synthesis in numbers: 15 tests pass natively, and the header pins the Artix-7 teaching delays the tree arithmetic uses.", "The MMCM model through the real compiler: VCO window, M/D/O ranges, fractional multiply in eighths, the 1/56 phase step, 16 tests natively.", "Widen the VCO window with one sed and exactly one test objects -- the rejection test that names the 500 MHz config it calls out.", "Static timing as arithmetic: 25 tests pass natively on arcs, slack and Fmax, with the Artix-7 teaching delays in the header.", "The three reset kinds through the real compiler: async assert with sync release through 2 to 4 flops, and the racy async release, 16 tests natively.", "What the compiler emits for the reset pipe: t27c gen prints the Zig, one struct copy per clock, and wc -l counts it.", "Metastability MTBF without floats: the WP323 form in Q10 log2, one flop negative slack, two flops astronomical, 15 tests natively.", "The CDC model as Zig: t27c gen prints what it compiled and wc -l says how many lines of code the model is.", "The FIFO stdlib through the real compiler: 18 tests pass natively and 6 invariants are proved comptime.", "Move a pointer by 3 instead of 1 and every test still passes: the suite asserts fill and flags, never pointer values.", "Flip one flag assignment and a single test objects: the guard that keeps the FIFO honest.", "The pins-to-XDC emitter spec parsed by the real compiler, and the create_clock lines it exists to write.", "The fpga-rxcap tool card as a spec: constants for a tool page, and a native run that says 0 tests and why.", "168 records: 14 papers entered twice, 141 cite no score, 144 state zero at pass@1.", "67 specs lose 23,578 tokens to parser recovery, each held at its pinned bound.", "Smallest hold 3445 ps on TXD1 against a 1000 ps bench; each TX pin setup and hold from the routed SDF.", "Per-bit setup and hold of an async RX nibble against its RXC edge, from the routed SDF: one nibble changes 2387 to 2486 ps apart, so a binary counter tears where a gray one cannot.", "RX_ER pulses injected at exact nibble positions of a ping -- preamble, mid-frame, IP header -- and the frame state each pulse leaves behind, RTL vs model.", "The Ethernet bring-up plan on the bench: pre-registered steps, logged exits, what ran and what did not.", "The registered IO clients on the bench, read live: names, claims and what each declares it owns.", "The bench claim in action: one client takes the hardware lock and the tool reports who holds it.", "The bench lock given back: the client gives up its claim and the bench reports itself free.", "The next queued step on the bench, read live from the run state.", "The memory map spec through the real compiler: 15 tests pass natively and 6 invariants are proved comptime.", "The SPI testbench through the real compiler: 7 tests pass natively, driving the modes and checking the captures.", "t27c check on the UART spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the SPI spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the APB bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the AXI4 spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the bus bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the memory spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "The UART spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The SPI spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The APB bridge spec lowered to synthesizable Verilog: port list, PSEL and PENABLE wiring, the address decode.", "The AXI4 spec lowered to synthesizable Verilog: the five channels' wiring and handshakes as generated wires.", "The bus bridge spec lowered to synthesizable Verilog: both sides of the crossing as generated wires.", "The whole design in one spec lowered to synthesizable Verilog: clocks, resets and bus wiring as the compiler emits them.", "The UART testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The APB bridge testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The AXI4 testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The memory testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The integration testbench spec lowered to Verilog: every bus of the design in one bench.", "The top-level testbench spec lowered to Verilog: the whole design under one bench.", "The SPI testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The UART spec lowered to hardware IR: the compiler's own view of the wires and state before Verilog exists.", "The APB bridge spec lowered to hardware IR: PSEL, PENABLE and the decode as the compiler structures them.", "The AXI4 spec lowered to hardware IR: the five channels and their handshakes as the compiler structures them.", "The Ethernet FCS spec through the real compiler: 8 tests pass natively -- the table derived from one bit step, the 0xCBF43926 check value, the 0xDEBB20E3 receiver residue.", "The RGMII spec through the real compiler: 7 tests pass natively and 1 invariant is proved comptime -- the 8 ns gigabit period, a nibble on both edges, the 78 ps tap ladder.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "The t27 compiler running as WebAssembly in a post: compile, test, seven backends.", "The same spec as Rust, printed by a terminal in the page.", "The only backend that runs in the browser: generate the module, then run it.", "t27c on hello_world.t27, on a real machine, every byte as printed.", "Code that compiles and is wrong: the tool that finds it.", "", "", "The OCP MX scale byte as a spec: 2^(e-127), code 255 is NaN, 18 tests and 9 comptime invariants, compiled on a real machine.", "The same scale byte compiled in your browser: seven backends, the spec's tests run in the page, and every skip says why.", "One outlier sets the scale for 32 weights: MXFP4 flushes 23 of them to zero, MXFP8 E4M3 none. 49 tests pass; a planted bug fails one.", "Ternary weights scaled by phi, compiled in your browser: codes 00, 01, 10, and the fourth code folded to zero.", "13 of 13 tests pass natively, and the report says 8 of them executed no assert; a planted bug fails exactly one.", "Five measured rules for a ternary weight alphabet, and the one formula that passes all five, run in your browser.", "One more trit and the spec does not compile at all: BLOCKED, not failed, because no test ever ran.", "A 17-bit float whose exponent is four balanced trits, 3^4 = 81 values, compiled in your browser.", "34 tests pass natively, none vacuous; swap one XOR for OR and only the test that negates twice fails.", "A neuron's sum squeezed back to one trit: 7 tests pass natively, and turning one > into >= fails only the boundary test.", "One ternary neuron, two functions picked by its weights: 12 tests pass natively, and one weight moved from P to Z fails exactly one.", "A neuron wider than 27 inputs, summed chunk by chunk: 11 tests pass natively, and a loop that stops after one chunk fails exactly one.", "A 27-lane ternary dot product as pure wires: 4 tests pass natively, and one wrong sign in tmul fails exactly one.", "The same dot product added into a register on every clock: 4 tests pass natively, and a lane mask short one bit fails exactly one.", "A whole small ternary network, 3 neurons then 2: 4 tests pass natively, and a trit packed one bit low fails exactly one.", "A signed multiply: 3 tests pass natively, none vacuous, and a sign stuck at 0 fails exactly one, m2.", "A signed add: 3 tests pass natively, and adding where opposite signs must subtract fails exactly one, a2.", "Two signed products summed: 4 tests pass natively, and OR in place of the sign XOR fails exactly one, pp.", "A ReLU: 4 tests pass natively, and letting negative inputs through fails only negz, the one test with a negative input.", "2^x for a softmax: 4 tests pass natively, and dropping the minus sign of k fails exactly one, em1.", "argmax by comparing bits alone: 4 tests pass natively, and >= in place of > fails exactly one, tie_low.", "A loss in bits: 3 tests pass natively, and a zero with the sign bit set fails exactly one, perfect.", "One SGD step: 3 tests pass natively, and g times g in place of eta times g fails exactly one, ascend.", "A 2-layer ReLU net for XOR: 4 tests pass natively, and one relu removed fails exactly one, x00.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "34 vector files, 512 cases: 2 files executed, 8 debt, 24 prose-only; 19% carry data.", "Four census populations recounted another way all agree; three are named as uncheckable.", "31 of 1,428 seals record no output (16 specs); 3 of those are missing from the debt ledger.", "11 specs refused at parse, 0 blocked only by prose, 23 broken on purpose as fixtures.", "12 Lean files, 15,553 lines and 4 sorry, are reached by no build root: nothing compiles them.", "tri, railway, python3 and the loop directory: each present or not, in one call.", "The terminal for seven t27 backends: every command run on hello_world. 21 pass, 0 fail.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Pick a lane and see whether the TRI decision layer beats the baseline on the same issue.", "One tick of the Queen's loop: an anomaly scan that reports only what changed.", "The loop's skills checked against snapshots before an agent may use them.", "Three performance bits, and one knockout bitstream per bit to prove each one matters.", "", "", "73 published posts with date, language and revision, newest first.", "6 of 6 self-tests hold: anomalies, blog_drift, lessons, site_gate, tick, vault."]; ; --- Ideas: asked for, not built --------------------------------------------------------------- ; From what engineers share today (gh-skyline, Tiny Tapeout renders, Wrapped cards, Gatle-style @@ -119,9 +119,9 @@ test the_fpga_shelf_comes_first_and_opens_on_the_board { } test the_arena_is_a_tab_and_says_its_own_words { - assert WIDGET_IDS[244] == "wars"; - assert WIDGET_KINDS[244] == "tab"; - assert WIDGET_PAGES[244] == "wars"; + assert WIDGET_IDS[271] == "wars"; + assert WIDGET_KINDS[271] == "tab"; + assert WIDGET_PAGES[271] == "wars"; } test the_gallery_posts_nothing { @@ -157,8 +157,8 @@ test the_verification_shelf_is_rehearsals_and_audits { test ideas_are_counted_apart_from_widgets { assert IDEA_COUNT == 6; - assert WIDGET_IDS[249] == "gatle"; - assert WIDGET_COUNT == 252; + assert WIDGET_IDS[276] == "gatle"; + assert WIDGET_COUNT == 279; } test the_ternary_machine_shelf_runs_before_the_arena { @@ -172,9 +172,9 @@ test every_tool_lives_under_widgets_and_keeps_its_words_on_its_page { assert WIDGET_KINDS[9] == "tool"; assert WIDGET_PAGES[9] == "widgets/bit-diff/"; assert WIDGET_HOOKS[9] == ""; - assert WIDGET_KINDS[248] == "tool"; - assert WIDGET_CATEGORIES[248] == "game"; - assert WIDGET_PAGES[248] == "widgets/race-the-bee/"; + assert WIDGET_KINDS[275] == "tool"; + assert WIDGET_CATEGORIES[275] == "game"; + assert WIDGET_PAGES[275] == "widgets/race-the-bee/"; } test the_arithmetic_shelf_closes_the_fpga_bench { @@ -185,3 +185,12 @@ test the_arithmetic_shelf_closes_the_fpga_bench { assert WIDGET_CATEGORIES[124] == "fpga"; assert WIDGET_HOOKS[124] == ""; } + +test the_neural_network_shelf_runs_before_the_arena { + assert WIDGET_IDS[244] == "nn-relu"; + assert WIDGET_KINDS[244] == "tool"; + assert WIDGET_PAGES[244] == "widgets/nn-relu/"; + assert WIDGET_IDS[270] == "nn-ppo"; + assert WIDGET_CATEGORIES[270] == "compiler"; + assert WIDGET_IDS[271] == "wars"; +} diff --git a/apps/website/public/widgets/nn-adam/card.png b/apps/website/public/widgets/nn-adam/card.png new file mode 100644 index 0000000000000000000000000000000000000000..4694baeb174c6f05c6b8b027a74d3e8109910680 GIT binary patch literal 50792 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�mA2z$wxpv2M%q6N==AN)hqG;dg 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 + + + + + +Adam: the optimizer most networks are trained with · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +

+Trinity S³AI +

Adam: the optimizer most networks are trained with

+

Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/optimizer/adam.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 18 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-adam/logic.js b/apps/website/public/widgets/nn-adam/logic.js new file mode 100644 index 0000000000..c404640df0 --- /dev/null +++ b/apps/website/public/widgets/nn-adam/logic.js @@ -0,0 +1,44 @@ +// Generated by scripts/t27-logic.mjs from adam.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 75f3d191b54ab786de3aa085164717813022eb8f403da12fe5b55c7bda8aa73f +// Imported by scripts/widget-logic.mjs for public/widgets/nn-adam/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABLAZgAX8BfWAIf39/f39/f38Bf2ACfX8BfWABfQF/YAJ9fQF9YAV9fX1/fwF9AwkIAAECAwQFAwIEBQFwAQEBBQMBABAGCQF/AUGAgMAACwdeBwZtZW1vcnkCAAt0MjdfZGVzY2VuZAAAC3QyN19hY2NlcHRzAAMJdDI3X3JhdGlvAAQOdDI3X2ZpcnN0X3N0ZXAABQ10MjdfaXNfZmluaXRlAAYIdDI3X3Bvd2kABwrlBwi+AQMBfwF9AX8jgICAgABBMGsiASSAgICAACABQQA2AhQgAUEANgIQIAFBADYCDEMAAAAAIQJBACEDAkADQCAAIANGDQEgAUEANgIsIAFC9/z++/OO85UyNwIkIAFCzZmz7uPMmbM/NwIcIAEgAkMAAEDAkiICIAKSOAIYIAFBDGpBASABQRhqQQEgAUEQaiABQRRqIANBAWoiAyABQRxqEIGAgIAAGiABKgIMIQIMAAsLIAFBMGokgICAgAAgAguxAgMFfQJ/BX0gByoCECEIIAcqAgwhCSAHKgIIIQogByoCBCELIAcqAgAhDEEAIQ0gAiEHAkACQANAIAMgDSIORg0BIA5BAWohDSAHKgIAIQ8gB0EEaiEHIA8gD1sgDyAPkyIPIA9bcQ0ADAILC0MAAIA/IAqTIRBDAACAPyALkyERQwAAgD8gCyAGEIKAgIAAkyESQwAAgD8gCiAGEIKAgIAAkyETA0AgAUUNASAEIAsgBCoCAJQgESACKgIAIAggACoCAJSSIg+UkjgCACAFIAogBSoCAJQgDyAQIA+UlJIiDzgCACAAIAAqAgAgDCAEKgIAIBKVlCAJIA8gE5WRkpWTOAIAIAVBBGohBSAEQQRqIQQgAEEEaiEAIAJBBGohAiABQX9qIQEMAAsLIA4gA08LKAEBfUMAAIA/IQICQANAIAFFDQEgAUF/aiEBIAAgApQhAgwACwsgAgueAQECfyOAgICAAEEwayIBJICAgIAAIAFBADYCLCABQvf8/vvzjvOVMjcCJCABQu+kjNTjzJmzPzcCHCABQQA2AhggAUEANgIUIAEgADgCECABQYCAgPwDNgIMIAFBDGpBASABQRBqQQEgAUEUaiABQRhqQQEgAUEcahCBgICAACECIAEqAgwhACABQTBqJICAgIAAIAIgAEMAAIA/XHELBwAgACABlQv+AQECfyOAgICAAEHQAGsiBSSAgICAACAFQTBqQQhqQQA2AgAgBUEgakEIakEANgIAIAVBADYCTCAFQvf8/vvzjvOVMjcCRCAFQu+kjNTjzJmzPzcCPCAFQgA3AzAgBUIANwMgIAUgAjgCHCAFIAE4AhggBSAAOAIUIAVBgICAggQ2AhAgBUKAgID8g4CAgMAANwIIIAVBCGpBAyAFQRRqQQMgBUEgaiAFQTBqQQEgBUE8ahCBgICAABogBUEgaiEGAkACQAJAIANBf2oOAgIAAQsgBUEwaiEGDAELIAVBCGohBgsgBiAEQQJ0aioCACECIAVB0ABqJICAgIAAIAILEgAgACAAWyAAIACTIgAgAFtxCwwAIAAgARCCgICAAAs="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function powi(b, t) { + return W.t27_powi(b, int(t, 0, 4294967295, "powi.t")); +} +function isFinite(x) { + return W.t27_is_finite(x) !== 0; +} +function firstStep(g0, g1, g2, which, index) { + return W.t27_first_step(g0, g1, g2, int(which, 0, 255, "first_step.which"), int(index, 0, 4294967295, "first_step.index")); +} +function ratio(a, b) { + return W.t27_ratio(a, b); +} +function accepts(g) { + return W.t27_accepts(g) !== 0; +} +function descend(steps) { + return W.t27_descend(int(steps, 0, 4294967295, "descend.steps")); +} +const __NOT_LOWERED__ = Object.freeze(["step", "cfg"]); +export { + __NOT_LOWERED__, + accepts, + descend, + firstStep, + isFinite, + powi, + ratio +}; diff --git a/apps/website/public/widgets/nn-adam/logic.t27 b/apps/website/public/widgets/nn-adam/logic.t27 new file mode 100644 index 0000000000..df8bd6334d --- /dev/null +++ b/apps/website/public/widgets/nn-adam/logic.t27 @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Adam adapts learning rate per parameter | φ² + 1/φ² = 3 | TRINITY + +// #8980: step only checked its gradients with an undeclared `math::is_finite` +// and updated nothing; the tests asserted `result != undefined`. step is now +// Adam (Kingma and Ba, 2015) with bias correction. It refuses (returns false, +// changes nothing) when a gradient is NaN or infinite, which is what the old body +// validated. + +module Adam; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_BETA1 : f32 = 0.9; + const DEFAULT_BETA2 : f32 = 0.999; + const DEFAULT_EPSILON : f32 = 1e-8; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const AdamConfig = struct { + learning_rate : f32, + beta1 : f32, + beta2 : f32, + epsilon : f32, + weight_decay : f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // b^t for a whole t >= 0 + fn powi(b: f32, t: u32) -> f32 { + var r : f32 = 1.0; + var n : u32 = 0; + while (n < t) { + r = r * b; + n = n + 1; + } + return r; + } + + // NaN is the one value not equal to itself; inf - inf is NaN + fn is_finite(x: f32) -> bool { + return x == x and (x - x) == (x - x); + } + + // One Adam step number t (1-based) over params, with moment buffers m and v: + // g = grad + wd p + // m = b1 m + (1 - b1) g v = b2 v + (1 - b2) g^2 + // m_hat = m / (1 - b1^t) v_hat = v / (1 - b2^t) + // p = p - lr m_hat / (sqrt(v_hat) + eps) + fn step(params: []f32, grads: []const f32, m: []f32, v: []f32, t: u32, config: AdamConfig) -> bool { + var i : usize = 0; + while (i < grads.len) { + if (!is_finite(grads[i])) { + return false; + } + i = i + 1; + } + const c1 = 1.0 - powi(config.beta1, t); + const c2 = 1.0 - powi(config.beta2, t); + i = 0; + while (i < params.len) { + const g = grads[i] + config.weight_decay * params[i]; + m[i] = config.beta1 * m[i] + (1.0 - config.beta1) * g; + v[i] = config.beta2 * v[i] + (1.0 - config.beta2) * g * g; + const m_hat = m[i] / c1; + const v_hat = v[i] / c2; + params[i] = params[i] - config.learning_rate * m_hat / (sqrt(v_hat) + config.epsilon); + i = i + 1; + } + return true; + } + + fn cfg(lr: f32) -> AdamConfig { + return AdamConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.0 }; + } + + // which: 0 = param, 1 = m, 2 = v after one step on params (1, 2, 3) with grads (g0, g1, g2) + fn first_step(g0: f32, g1: f32, g2: f32, which: u8, index: usize) -> f32 { + var params : [3]f32 = [1.0, 2.0, 3.0]; + const grads : [3]f32 = [g0, g1, g2]; + var m : [3]f32 = [0.0] ** 3; + var v : [3]f32 = [0.0] ** 3; + _ = step(¶ms, &grads, &m, &v, 1, cfg(0.001)); + if (which == 1) { + return m[index]; + } + if (which == 2) { + return v[index]; + } + return params[index]; + } + + // a / b at run time, where IEEE gives NaN for 0 / 0 and inf for 1 / 0 + fn ratio(a: f32, b: f32) -> f32 { + return a / b; + } + + fn accepts(g: f32) -> bool { + var params : [1]f32 = [1.0]; + const grads : [1]f32 = [g]; + var m : [1]f32 = [0.0]; + var v : [1]f32 = [0.0]; + return step(¶ms, &grads, &m, &v, 1, cfg(0.001)) and params[0] != 1.0; + } + + // Minimise (x - 3)^2 from 0 + fn descend(steps: u32) -> f32 { + var params : [1]f32 = [0.0]; + var m : [1]f32 = [0.0]; + var v : [1]f32 = [0.0]; + var t : u32 = 1; + while (t <= steps) { + const grads : [1]f32 = [2.0 * (params[0] - 3.0)]; + _ = step(¶ms, &grads, &m, &v, t, cfg(0.1)); + t = t + 1; + } + return params[0]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // Bias correction makes the first step lr * sign(g), whatever |g| is + test step_basic_case + given p0 = first_step(0.1, -5.0, 0.0, 0, 0) + when p1 = first_step(0.1, -5.0, 0.0, 0, 1) + then @abs(p0 - 0.999) < 0.000001 and @abs(p1 - 2.001) < 0.000001 and first_step(0.1, -5.0, 0.0, 0, 2) == 3.0 + + // m = 0.1 g and v = 0.001 g^2 after the first step + test step_with_gradients + given m2 = first_step(0.1, 0.2, 0.3, 1, 2) + when v2 = first_step(0.1, 0.2, 0.3, 2, 2) + then @abs(m2 - 0.03) < 0.0000001 and @abs(v2 - 0.00009) < 0.0000001 + + // Finite gradients are applied; NaN and inf are refused + test step_validates_gradients + given ok = accepts(1.5) and accepts(-2.3) and accepts(4.7) + when refused = !accepts(ratio(0.0, 0.0)) and !accepts(ratio(1.0, 0.0)) + then ok and refused + + test step_descends_a_quadratic + given result = descend(500) + then @abs(result - 3.0) < 0.01 + + invariant adam_betas_are_below_one + assert DEFAULT_BETA1 < 1.0 and DEFAULT_BETA2 < 1.0 and DEFAULT_BETA1 < DEFAULT_BETA2 and DEFAULT_EPSILON > 0.0 diff --git a/apps/website/public/widgets/nn-adam/nn-adam.t27 b/apps/website/public/widgets/nn-adam/nn-adam.t27 new file mode 100644 index 0000000000..df20f42a52 --- /dev/null +++ b/apps/website/public/widgets/nn-adam/nn-adam.t27 @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-adam.t27 -- Adam: momentum, a running scale and the bias correction +; Source of truth for public/widgets/nn-adam/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-adam/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/adam.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 18 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets the number of steps and three gradients from -50 to 50. The path is +; descend(n) of the spec (lr 0.1 on (x - 3)^2 from 0); the bars and tiles are first_step(g0, g1, g2, +; which, i) on weights (1, 2, 3) at lr 0.001. + +; WHAT IT DOES NOT CLAIM: the bowl is one weight, as in the SGD lesson, so the two paths can be +; compared, not ranked. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_adam; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-adam"; +pub const TITLE : str = "Adam: the optimizer most networks are trained with"; +pub const DESCRIPTION : str = "Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size."; +pub const IMAGE_ALT : str = "Adam card: the green path rises from 0, passes the white dashed minimum at 3, peaks near 3.18 and settles at 3.00005 by step 200. Below, three bars of the first moment m read 0.20, -4.00 and 0.05 while the weights read 0.9990, 2.0010 and 2.9990. Tiles read x 3.00005 and step 1 at 0.1000."; +pub const HOOK : str = "Gradients 2, -40 and 0.5 all move their weights by exactly 0.001 on step 1. Adam reaches 3.00005 in 200 steps at lr 0.1."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/adam.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 18 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 200; +pub const K_MINIMUM : u8 = 3; +pub const K_Y_LO : u8 = 0; +pub const K_Y_HI : u8 = 4; +pub const K_Y_TICKS : [5]u8 = [0, 1, 2, 3, 4]; +pub const K_STEP_TICKS : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_G_LO_C : i16 = -5000; +pub const K_G_HI_C : u16 = 5000; +pub const K_BAR_LO : i8 = -5; +pub const K_BAR_HI : u8 = 5; +pub const K_BAR_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_PRESET_STEPS : [4]u8 = [200, 10, 50, 200]; +pub const K_PRESET_G0_C : [4]i16 = [200, 100, -100, 5000]; +pub const K_PRESET_G1_C : [4]i16 = [-4000, 100, -100, 1]; +pub const K_PRESET_G2_C : [4]i16 = [50, 100, -100, -5000]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["200 steps; g 2, -40, 0.5", "10 steps; equal g", "50 steps; negative g", "200 steps; g 50, 0.01, -50"]; +pub const SAY_ASK : str = "Why is Adam the optimizer most networks are trained with?"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_G : str = "gradient"; +pub const SAY_W : str = "w"; +pub const SAY_PLOT_LABEL : str = "The weight after every Adam step, from 0 toward the minimum at 3"; +pub const SAY_FIRST_LABEL : str = "Step 1 on weights 1, 2, 3: the first moment m and the weight after"; +pub const SAY_PATH : str = "Adam, lr 0.1"; +pub const SAY_MIN : str = "the minimum"; +pub const SAY_X_NOW : str = "x after the steps"; +pub const SAY_X_ONE : str = "after step 1"; +pub const SAY_W_AFTER : str = "weights after step 1"; +pub const SAY_V : str = "second moment v"; +pub const SAY_NOTE : str = "m and v start at zero, so early on they are too small; dividing by 1 - beta^t corrects them. On step 1 that makes m / sqrt(v) exactly the sign of the gradient."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/adam.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_gradients_are_symmetric { + assert K_G_LO_C + K_G_HI_C == 0; + assert K_PRESET_G0_C[3] == K_G_HI_C; + assert K_PRESET_G2_C[3] == K_G_LO_C; +} + +test the_minimum_is_inside_the_axis { + assert K_MINIMUM == 3; + assert K_Y_HI > K_MINIMUM; + assert K_PRESET_STEPS[0] == K_STEPS_HI; +} diff --git a/apps/website/public/widgets/nn-adam/tool.js b/apps/website/public/widgets/nn-adam/tool.js new file mode 100644 index 0000000000..8ce8c40385 --- /dev/null +++ b/apps/website/public/widgets/nn-adam/tool.js @@ -0,0 +1,44 @@ +// nn-adam/tool.js -- lesson 18 of neural-networks: the optimizer most networks are trained with. +// Adam keeps a running mean of the gradient (m) and of its square (v), corrects both for starting at +// zero, and steps by m / sqrt(v): so its first step is lr times the sign of the gradient, whatever +// its size. Every point is descend and every bar first_step of gHashTag/t27 +// specs/ml/optimizer/adam.t27, compiled to wasm (./logic.js). Words are SAY_ and numbers K_ constants +// of specs/widgets/nn-adam.t27. +import { descend, firstStep } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, say, source, svgEl, tiles } from '../nn-kit.js' + +const NMAX = K('K_STEPS_HI', 200) +const MIN = K('K_MINIMUM', 3) +const G0 = centi(K('K_G_LO_C', -5000)), G1 = centi(K('K_G_HI_C', 5000)) +const grad = (key, i) => ({ key, label: `${say('SAY_G')} ${i}`, min: G0, max: G1, step: 0.5, fmt: (v) => fmt(v, 1) }) +const ctl = controls([ + { key: 'n', label: say('SAY_STEPS'), min: 1, max: NMAX }, + grad('g0', 0), grad('g1', 1), grad('g2', 2), +], { names: W.SAY_PRESET_NAMES, values: { n: K('K_PRESET_STEPS', []), g0: K('K_PRESET_G0_C', []).map(centi), g1: K('K_PRESET_G1_C', []).map(centi), g2: K('K_PRESET_G2_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const first = canvas('nn-bars', say('SAY_FIRST_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_PATH'), COLORS[0]], [say('SAY_MIN'), '#ffffff', true]]), el('p', { class: 'dk-label' }, say('SAY_FIRST_LABEL')), first, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 320, x0: 0, x1: NMAX, y0: K('K_Y_LO', 0), y1: K('K_Y_HI', 4), xticks: K('K_STEP_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_STEPS') } + const p = plot(svg, o) + svg.append(svgEl('line', { x1: p.left, x2: 640 - p.right, y1: p.clampY(MIN), y2: p.clampY(MIN), stroke: '#fff', 'stroke-dasharray': '6 6', opacity: 0.7 })) + p.line([...Array(NMAX + 1)].map((_, k) => [k, descend(k)]), COLORS[0], 3) + cursor(svg, p, s.n, [[descend(s.n), COLORS[1]]]) + dragX(svg, p, o, (n) => ctl.set('n', Math.round(n))) + // Bars: the first moment m, which grows with the gradient; under each, the weight after the step, + // which moves by the same lr whatever the gradient was. + const m = [0, 1, 2].map((i) => firstStep(s.g0, s.g1, s.g2, 1, i)) + bars(first, { values: m, labels: [0, 1, 2].map((i) => `${say('SAY_W')} ${i} = ${fmt(firstStep(s.g0, s.g1, s.g2, 0, i), 4)}`), colors: m.map((v) => (v < 0 ? COLORS[3] : COLORS[0])), lo: K('K_BAR_LO', -5), hi: K('K_BAR_HI', 5), h: 230, ticks: K('K_BAR_TICKS', []), fmt: (v) => `m ${fmt(v, 2)}` }) + stat.replaceChildren(tiles([ + { label: say('SAY_X_NOW'), value: fmt(descend(s.n), 5), tone: 0 }, + { label: say('SAY_X_ONE'), value: fmt(descend(1), 4), tone: 1 }, + { label: say('SAY_W_AFTER'), value: [0, 1, 2].map((i) => fmt(firstStep(s.g0, s.g1, s.g2, 0, i), 4)).join(' '), tone: 2 }, + { label: say('SAY_V'), value: [0, 1, 2].map((i) => fmt(firstStep(s.g0, s.g1, s.g2, 2, i), 4)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-attention/card.png b/apps/website/public/widgets/nn-attention/card.png new file mode 100644 index 0000000000000000000000000000000000000000..0c6baf600b072d12c725f9d0b0f56602915477d0 GIT binary patch literal 51279 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-attention/index.html b/apps/website/public/widgets/nn-attention/index.html new file mode 100644 index 0000000000..b66fd3e65e --- /dev/null +++ b/apps/website/public/widgets/nn-attention/index.html @@ -0,0 +1,47 @@ + + + + + + +Attention: how a word decides which other words to read · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Attention: how a word decides which other words to read

+

Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 24 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-attention/logic.js b/apps/website/public/widgets/nn-attention/logic.js new file mode 100644 index 0000000000..6c908634c9 --- /dev/null +++ b/apps/website/public/widgets/nn-attention/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from attention_mechanism.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: f3f3c3bf7bd4d4d79173dc34896aa185857d5abc3e8684c3bfcd949547c9b591 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-attention/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forwardAt(causal, which, index) { + return W.t27_forward_at(causal ? 1 : 0, int(which, 0, 255, "forward_at.which"), int(index, 0, 4294967295, "forward_at.index")); +} +function loss(which, index, delta) { + return W.t27_loss(int(which, 0, 255, "loss.which"), int(index, 0, 4294967295, "loss.index"), delta); +} +function grad(which, index, dropout) { + return W.t27_grad(int(which, 0, 255, "grad.which"), int(index, 0, 4294967295, "grad.index"), dropout); +} +function slope(which, index) { + return W.t27_slope(int(which, 0, 255, "slope.which"), int(index, 0, 4294967295, "slope.index")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["seq_of", "scale_of", "forward", "backward", "cfg", "fixture"]); +export { + __NOT_LOWERED__, + forwardAt, + grad, + loss, + slope, + validInput +}; diff --git a/apps/website/public/widgets/nn-attention/logic.t27 b/apps/website/public/widgets/nn-attention/logic.t27 new file mode 100644 index 0000000000..48dce23e6c --- /dev/null +++ b/apps/website/public/widgets/nn-attention/logic.t27 @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Memory-efficient attention for long sequences | φ² + 1/φ² = 3 | TRINITY + +// #8980: redeclared `var i` in one scope four times, called `@infinity()` and +// `@random()` (not Zig), and indexed every row as head_dim wide inside d_model-wide +// rows. backward also skipped the softmax Jacobian: it pushed dL/dweights straight +// into the scores. It is now multi-head scaled dot-product attention over seq x +// d_model rows. Head h reads columns h*hd .. (h+1)*hd, the weights are +// heads x seq x seq, and causal masking is optional. backward is the exact +// gradient, checked against finite differences. Dropout is carried in the config +// and not applied: this is the inference computation. + +module Attention; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const NEG_INF : f32 = -1.0e30; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const AttentionConfig = struct { + d_model : u32, + num_heads : u32, + dropout : f32, + causal : bool, + }; + + pub const AttentionOutput = struct { + output : []f32, + weights : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + fn seq_of(query: []const f32, config: AttentionConfig) -> usize { + return query.len / config.d_model; + } + + fn scale_of(config: AttentionConfig) -> f32 { + return 1.0 / sqrt(@as(f32, @floatFromInt(config.d_model / config.num_heads))); + } + + fn forward(query: []const f32, key: []const f32, value: []const f32, output: []f32, weights: []f32, config: AttentionConfig) -> void { + const n = seq_of(query, config); + const d : usize = config.d_model; + const hd : usize = config.d_model / config.num_heads; + const scale = scale_of(config); + var h : usize = 0; + while (h < config.num_heads) { + var i : usize = 0; + while (i < n) { + const row = weights[(h * n + i) * n .. (h * n + i + 1) * n]; + var max_s : f32 = NEG_INF; + var j : usize = 0; + while (j < n) { + var score : f32 = NEG_INF; + if (!(config.causal and j > i)) { + score = 0.0; + var k : usize = 0; + while (k < hd) { + score = score + query[i * d + h * hd + k] * key[j * d + h * hd + k]; + k = k + 1; + } + score = score * scale; + } + row[j] = score; + max_s = @max(max_s, score); + j = j + 1; + } + var sum : f32 = 0.0; + j = 0; + while (j < n) { + row[j] = exp(row[j] - max_s); + sum = sum + row[j]; + j = j + 1; + } + j = 0; + while (j < n) { + row[j] = row[j] / sum; + j = j + 1; + } + var k : usize = 0; + while (k < hd) { + var acc : f32 = 0.0; + j = 0; + while (j < n) { + acc = acc + row[j] * value[j * d + h * hd + k]; + j = j + 1; + } + output[i * d + h * hd + k] = acc; + k = k + 1; + } + i = i + 1; + } + h = h + 1; + } + } + + // dV_j += P_ij dO_i; dP_ij = dO_i . V_j; dS_ij = P_ij (dP_ij - sum_k P_ik dP_ik); + // dQ_i += scale dS_ij K_j; dK_j += scale dS_ij Q_i (per head; masked P_ij are 0) + fn backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) -> void { + const n = seq_of(query, config); + const d : usize = config.d_model; + const hd : usize = config.d_model / config.num_heads; + const scale = scale_of(config); + var x : usize = 0; + while (x < n * d) { + grad_query[x] = 0.0; + grad_key[x] = 0.0; + grad_value[x] = 0.0; + x = x + 1; + } + var h : usize = 0; + while (h < config.num_heads) { + var i : usize = 0; + while (i < n) { + const p = attn_weights[(h * n + i) * n .. (h * n + i + 1) * n]; + var row_dot : f32 = 0.0; + var j : usize = 0; + while (j < n) { + var dp : f32 = 0.0; + var k : usize = 0; + while (k < hd) { + dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k]; + grad_value[j * d + h * hd + k] = grad_value[j * d + h * hd + k] + p[j] * grad_output[i * d + h * hd + k]; + k = k + 1; + } + row_dot = row_dot + p[j] * dp; + j = j + 1; + } + j = 0; + while (j < n) { + var dp : f32 = 0.0; + var k : usize = 0; + while (k < hd) { + dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k]; + k = k + 1; + } + const ds = p[j] * (dp - row_dot) * scale; + k = 0; + while (k < hd) { + grad_query[i * d + h * hd + k] = grad_query[i * d + h * hd + k] + ds * key[j * d + h * hd + k]; + grad_key[j * d + h * hd + k] = grad_key[j * d + h * hd + k] + ds * query[i * d + h * hd + k]; + k = k + 1; + } + j = j + 1; + } + i = i + 1; + } + h = h + 1; + } + } + + fn cfg(causal: bool, dropout: f32) -> AttentionConfig { + return AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = dropout, .causal = causal }; + } + + // The fixture: seq 3, d_model 4, 2 heads (columns 0-1 and 2-3); q / k / v scaled down so the + // softmax is not saturated. which: 0 = output, 1 = weights. + fn fixture(q: []f32, k: []f32, v: []f32) -> void { + var x : usize = 0; + while (x < 12) { + q[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + k[x] = @as(f32, @floatFromInt(x / 4 + 1)) / 4.0 - @as(f32, @floatFromInt(x % 2)) / 3.0; + v[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + x = x + 1; + } + } + + fn forward_at(causal: bool, which: u8, index: usize) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + var out : [12]f32 = [9.0] ** 12; + var w : [18]f32 = [9.0] ** 18; + forward(&q, &k, &v, &out, &w, cfg(causal, 0.0)); + if (which == 0) { + return out[index]; + } + return w[index]; + } + + // L = sum_x g_x O_x with g_x = (x + 1) / 10, one entry of q, k or v moved by delta + // (which: 0 = q, 1 = k, 2 = v) + fn loss(which: u8, index: usize, delta: f32) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + if (which == 0) { + q[index] = q[index] + delta; + } + if (which == 1) { + k[index] = k[index] + delta; + } + if (which == 2) { + v[index] = v[index] + delta; + } + var out : [12]f32 = undefined; + var w : [18]f32 = undefined; + forward(&q, &k, &v, &out, &w, cfg(false, 0.0)); + var total : f32 = 0.0; + var x : usize = 0; + while (x < 12) { + total = total + @as(f32, @floatFromInt(x + 1)) / 10.0 * out[x]; + x = x + 1; + } + return total; + } + + fn grad(which: u8, index: usize, dropout: f32) -> f32 { + var q : [12]f32 = undefined; + var k : [12]f32 = undefined; + var v : [12]f32 = undefined; + fixture(&q, &k, &v); + var out : [12]f32 = undefined; + var w : [18]f32 = undefined; + forward(&q, &k, &v, &out, &w, cfg(false, dropout)); + var g : [12]f32 = undefined; + var x : usize = 0; + while (x < 12) { + g[x] = @as(f32, @floatFromInt(x + 1)) / 10.0; + x = x + 1; + } + var gq : [12]f32 = undefined; + var gk : [12]f32 = undefined; + var gv : [12]f32 = undefined; + backward(&g, &q, &k, &v, &w, &gq, &gk, &gv, cfg(false, dropout)); + if (which == 0) { + return gq[index]; + } + if (which == 1) { + return gk[index]; + } + return gv[index]; + } + + fn slope(which: u8, index: usize) -> f32 { + return (loss(which, index, 0.001) - loss(which, index, -0.001)) / 0.002; + } + + fn valid_input() -> u32 { + return cfg(false, 0.0).d_model % cfg(false, 0.0).num_heads; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // Each weight row is a distribution, and each output is a weighted mean of the values + // (so it lies between the smallest and largest value in its column) + test forward_basic_case { + const row_sum = forward_at(false, 1, 0) + forward_at(false, 1, 1) + forward_at(false, 1, 2); + assert(@abs(row_sum - 1.0) < 0.000001); + assert(forward_at(false, 0, 0) + forward_at(false, 0, 1) + forward_at(false, 0, 2) + forward_at(false, 0, 3) > 0.0); // computed a meaningful output + assert(forward_at(false, 0, 0) > 0.1 and forward_at(false, 0, 0) < 0.9); + } + + // dQ, dK and dV against central differences of L = g . O + test backward_basic_case { + assert(@abs(grad(0, 0, 0.0) - slope(0, 0)) < 0.001); + assert(@abs(grad(0, 7, 0.0) - slope(0, 7)) < 0.001); + assert(@abs(grad(1, 5, 0.0) - slope(1, 5)) < 0.001); + assert(@abs(grad(2, 10, 0.0) - slope(2, 10)) < 0.001); + assert(grad(0, 0, 0.0) + grad(0, 1, 0.0) + grad(0, 2, 0.0) + grad(0, 3, 0.0) != 0.0); // computed gradients + } + + // Position 0 attends only to itself, position 1 to positions 0 and 1 + test forward_causal_masking { + assert(forward_at(true, 1, 0) == 1.0); + assert(forward_at(true, 1, 1) == 0.0 and forward_at(true, 1, 2) == 0.0); + assert(forward_at(true, 1, 1 * 3 + 2) < 0.999); + assert(forward_at(true, 1, 1 * 3 + 2) == 0.0); + assert(forward_at(true, 0, 0) == 0.1); + } + + // Dropout is not applied here (inference), so it leaves the gradients unchanged + test backward_dropout { + assert(grad(2, 3, 0.5) == grad(2, 3, 0.0)); + assert(grad(0, 11, 0.5) == grad(0, 11, 0.0)); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // d_model % num_heads == 0 + invariant attention_constraint_0 + assert valid_input() == 0 + + // 0 <= dropout < 1 + invariant attention_constraint_1 + assert cfg(false, 0.5).dropout >= 0.0 and cfg(false, 0.5).dropout < 1.0 + + // query.shape == key.shape == value.shape: seq is read from the query + invariant attention_constraint_2 + assert cfg(false, 0.0).d_model == 4 diff --git a/apps/website/public/widgets/nn-attention/nn-attention.t27 b/apps/website/public/widgets/nn-attention/nn-attention.t27 new file mode 100644 index 0000000000..32f3a9f038 --- /dev/null +++ b/apps/website/public/widgets/nn-attention/nn-attention.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-attention.t27 -- scaled dot-product attention with two heads and a causal mask +; Source of truth for public/widgets/nn-attention/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-attention/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 24 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles the causal mask and taps a query row. Every weight is +; forward_at(causal, 1, i) and every output forward_at(causal, 0, i) of the spec: 3 positions, +; d_model 4, 2 heads, its own q, k and v. + +; WHAT IT DOES NOT CLAIM: q, k and v are the spec's fixture, not learned projections of real tokens. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_attention; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-attention"; +pub const TITLE : str = "Attention: how a word decides which other words to read"; +pub const DESCRIPTION : str = "Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future."; +pub const IMAGE_ALT : str = "Attention card, causal: two 3 x 3 grids in blue to white. Head 0 reads 1.000 / 0.452 0.548 / 0.230 0.321 0.449 with the upper triangle at 0; head 1 1.000 / 0.434 0.566 / 0.210 0.316 0.474. Row 2 is outlined. Below, a 3 x 4 output grid; position 2 outputs 0.59 0.69 0.81 0.91."; +pub const HOOK : str = "Causal: position 0 reads only itself (1.000), position 1 splits 0.45 / 0.55, position 2 spreads 0.23, 0.32, 0.45. Every row is a softmax."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 24 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SEQ : u8 = 3; +pub const K_D_MODEL : u8 = 4; +pub const K_HEADS : u8 = 2; +pub const K_PRESET_CAUSAL : [3]u8 = [1, 0, 1]; +pub const K_PRESET_Q : [3]u8 = [2, 2, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["Causal, position 2", "Full, position 2", "Causal, position 1"]; +pub const SAY_ASK : str = "How does a word decide which other words to read?"; +pub const SAY_CAUSAL : str = "causal mask"; +pub const SAY_HEAD : str = "head"; +pub const SAY_POS : str = "pos"; +pub const SAY_DIM : str = "dim"; +pub const SAY_ROWS : str = "rows are queries, columns keys"; +pub const SAY_TAP : str = "Tap a row to follow one query."; +pub const SAY_OUT_LABEL : str = "The output: each position's weighted average of the values"; +pub const SAY_MASK : str = "mask"; +pub const SAY_MASK_ON : str = "no reading ahead"; +pub const SAY_MASK_OFF : str = "every key"; +pub const SAY_OUT_ROW : str = "output of {0}"; +pub const SAY_NOTE : str = "Each weight is softmax(q . k / sqrt(d)) over the keys of its row; the output is the values averaged by those weights. Two heads look at different halves of the vector."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/attention_mechanism.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test two_heads_split_the_model { + assert K_HEADS * 2 == K_D_MODEL; + assert K_SEQ == 3; +} + +test the_presets_stay_in_range { + assert K_PRESET_Q[0] < K_SEQ; + assert K_PRESET_CAUSAL[0] == 1; + assert K_PRESET_CAUSAL[1] == 0; +} diff --git a/apps/website/public/widgets/nn-attention/tool.js b/apps/website/public/widgets/nn-attention/tool.js new file mode 100644 index 0000000000..8460014cda --- /dev/null +++ b/apps/website/public/widgets/nn-attention/tool.js @@ -0,0 +1,37 @@ +// nn-attention/tool.js -- lesson 24 of neural-networks: how a word decides which other words to read. +// Attention scores every query against every key, turns each row of scores into weights with a +// softmax and averages the values by them; a causal mask stops a position from reading the future. +// Every weight and output is forward_at of gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27, +// compiled to wasm (./logic.js): 3 positions, d_model 4, 2 heads, the spec's own q, k and v. Words +// are SAY_ and numbers K_ constants of specs/widgets/nn-attention.t27. +import { forwardAt } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fill, fmt, heat, heatTone, root, say, source, tiles, tone } from '../nn-kit.js' + +const N = K('K_SEQ', 3), D = K('K_D_MODEL', 4), H = K('K_HEADS', 2) +const ctl = controls([ + { key: 'causal', label: say('SAY_CAUSAL'), kind: 'toggle' }, + { key: 'q', kind: 'hidden', min: 0, max: 2 }, +], { names: W.SAY_PRESET_NAMES, values: { causal: K('K_PRESET_CAUSAL', []), q: K('K_PRESET_Q', []) } }, draw) + +const heads = [...Array(H)].map((_, h) => canvas('nn-heat', `${say('SAY_HEAD')} ${h}`)) +const out = canvas('nn-heat', say('SAY_OUT_LABEL')) +const stat = el('div') +const pos = [...Array(N)].map((_, i) => `${say('SAY_POS')} ${i}`) +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('p', { class: 'dk-note' }, say('SAY_TAP')), + el('div', { class: 'nn-two' }, ...heads.map((svg, h) => el('div', {}, el('p', { class: 'dk-label' }, `${say('SAY_HEAD')} ${h}: ${say('SAY_ROWS')}`), svg))), + el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out, stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const c = !!s.causal + const w = (h, i, j) => forwardAt(c, 1, (h * N + i) * N + j) + heads.forEach((svg, h) => heat(svg, { rows: N, cols: N, value: (i, j) => w(h, i, j), color: (v) => heatTone(v), rowLabels: pos, colLabels: pos, labelWidth: 70, w: 400, cell: 100, fmt: (v) => fmt(v, 3), mark: (i) => (i === s.q ? 'on' : ''), onTap: (i) => ctl.set('q', i) })) + heat(out, { rows: N, cols: D, value: (i, k) => forwardAt(c, 0, i * D + k), color: (v) => tone(v, 1.2), rowLabels: pos, colLabels: [...Array(D)].map((_, k) => `${say('SAY_DIM')} ${k}`), labelWidth: 70, w: 640, cell: 110, fmt: (v) => fmt(v, 3), mark: (i) => (i === s.q ? 'on' : ''), onTap: (i) => ctl.set('q', i) }) + stat.replaceChildren(tiles([ + { label: `${say('SAY_HEAD')} 0, ${pos[s.q]}`, value: [0, 1, 2].map((j) => fmt(w(0, s.q, j), 3)).join(' '), tone: 2 }, + { label: `${say('SAY_HEAD')} 1, ${pos[s.q]}`, value: [0, 1, 2].map((j) => fmt(w(1, s.q, j), 3)).join(' '), tone: 3 }, + { label: say('SAY_MASK'), value: c ? say('SAY_MASK_ON') : say('SAY_MASK_OFF'), tone: c ? 1 : 5 }, + { label: fill(say('SAY_OUT_ROW'), pos[s.q]), value: [0, 1, 2, 3].map((k) => fmt(forwardAt(c, 0, s.q * D + k), 2)).join(' '), tone: 0 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-backprop/card.png b/apps/website/public/widgets/nn-backprop/card.png new file mode 100644 index 0000000000000000000000000000000000000000..20586d19b81e2f07e858a3f6ba61083ab081067b GIT binary patch literal 56839 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 + + + + + +Backpropagation: how blame flows back through a layer · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Backpropagation: how blame flows back through a layer

+

Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/dense_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 19 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-backprop/logic.js b/apps/website/public/widgets/nn-backprop/logic.js new file mode 100644 index 0000000000..247b5bdd4b --- /dev/null +++ b/apps/website/public/widgets/nn-backprop/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from dense_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: c756c98dad128be955c1a56ed60b9ea25d6108c91f92065f69f5a8d76ce0422b +// Imported by scripts/widget-logic.mjs for public/widgets/nn-backprop/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABNAdgAAF9YAR9fX1/AX1gBX9/f39/AGAAAX9gB39/f39/f38AYAR9fX9/AX1gBX19fX19AX0DCQgAAQIDBAMFBgQFAXABAQEFAwEAEQYJAX8BQYCAwAALB3kGBm1lbW9yeQIAD3QyN192YWxpZF9pbnB1dAAAHHQyN19lbXB0eV9iYWNrd2FyZF91bnRvdWNoZWQAAxt0MjdfZW1wdHlfZm9yd2FyZF91bnRvdWNoZWQABQ90MjdfYmFja3dhcmRfYXQABgt0MjdfbG9zc19hdAAHCsgICBkAQwAAgD9DAAAAQEMAAEBAQQAQgYCAgAALgQEBAX8jgICAgABBMGsiBCSAgICAACAEIAI4AhQgBCABOAIQIAQgADgCDCAEQgA3AxggBEKDgICAIDcCICAEQQE7ASggBEEMakGAgMCAAEGYgMCAACAEQSBqIARBGGoQgoCAgAAgBEEYaiADQQJ0aioCACECIARBMGokgICAgAAgAgvTAQMGfwF9An8gAygCACIFQQJ0IQYgAygCBCEHQQAhCCADLQAIQQFxIQkgAy0ACUH/AXFBAUchCgNAAkACQAJAIAggB0YNAEMAAAAAIQsgCQ0BDAILDwsgAiAIQQJ0aioCACELCyAAIQwgASENIAUhAwJAA0AgA0UNASADQX9qIQMgCyANKgIAIAwqAgCUkiELIAxBBGohDCANQQRqIQ0MAAsLIAQgCEECdGogCyALQwAAAAAgC0MAAAAAXhsgChs4AgAgASAGaiEBIAhBAWohCAwACwtdAgF/AX0jgICAgABBEGsiACSAgICAACAAQYCAgIcENgIMQQRBBEEEQaCAwIAAIABBDGogAEEMaiAAQQxqEISAgIAAIAAqAgwhASAAQRBqJICAgIAAIAFDAADgQFsL6QEBCX8gAygCBCEHIAQhCCADKAIAIgkhAwJAA0ACQCADDQAgCUECdCEKQQAhCwNAIAsgB0YNAyAGIAtBAnQiA2ogACADaiIMKgIAOAIAIAEhDSACIQ4gBSEPIAQhAyAJIQgCQANAIAhFDQEgAyADKgIAIA4qAgAgDCoCAJSSOAIAIA8gDCoCACANKgIAlDgCACANQQRqIQ0gDkEEaiEOIA9BBGohDyADQQRqIQMgCEF/aiEIDAALCyACIApqIQIgBSAKaiEFIAtBAWohCwwACwsgCEEANgIAIAhBBGohCCADQX9qIQMMAAsLC1MCAX8BfSOAgICAAEEQayIAJICAgIAAIABBgICAhwQ2AgxBBEEEQQRBoIDAgAAgAEEMahCCgICAACAAKgIMIQEgAEEQaiSAgICAACABQwAA4EBbC5ACAQJ/I4CAgIAAQdAAayIEJICAgIAAIARBIGpBCGpBACkCwIDAgAA3AwAgBEEwakEAKQLIgMCAADcDACAEQRBqQQhqQQAoArSAwIAANgIAIARCgIDAiISAgIjBADcDOCAEQQApAriAwIAANwMgIARBACkCrIDAgAA3AxAgBCABOAIMIAQgADgCCCAEQQE6AEwgBEEBOwFIIARCg4CAgCA3AkAgBEEIakHQgMCAAEGAgMCAACAEQcAAaiAEQRBqIARBIGogBEE4ahCEgICAACAEQRBqIQUCQAJAAkAgAg4CAgABCyAEQSBqIQUMAQsgBEE4aiEFCyAFIANBAnRqKgIAIQEgBEHQAGokgICAgAAgAQslACADIAAgASACQQAQgYCAgACUIAQgACABIAJBARCBgICAAJSSCwtlAQBBgIDAAAtcAACAPwAAAEAAAEBAAACAvwAAAAAAAIA/AAAAPwAAAL8AAAAAAAAAAAEAAAAAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAAIA/AAAAQAAAQEA="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function lossAt(x0, x1, x2, g0, g1) { + return W.t27_loss_at(x0, x1, x2, g0, g1); +} +function backwardAt(g0, g1, which, index) { + return W.t27_backward_at(g0, g1, int(which, 0, 255, "backward_at.which"), int(index, 0, 4294967295, "backward_at.index")); +} +function emptyForwardUntouched() { + return W.t27_empty_forward_untouched() !== 0; +} +function emptyBackwardUntouched() { + return W.t27_empty_backward_untouched() !== 0; +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["activate", "forward", "backward", "cfg", "forward_at"]); +export { + __NOT_LOWERED__, + backwardAt, + emptyBackwardUntouched, + emptyForwardUntouched, + lossAt, + validInput +}; diff --git a/apps/website/public/widgets/nn-backprop/logic.t27 b/apps/website/public/widgets/nn-backprop/logic.t27 new file mode 100644 index 0000000000..a75924f73d --- /dev/null +++ b/apps/website/public/widgets/nn-backprop/logic.t27 @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Row-major weight layout for cache efficiency | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward and backward were empty placeholders, the tests asserted +// `result != undefined`, and the invariants asserted `true` over an undeclared +// `valid_input`. Dense is now y = act(W x + b) with W row-major +// (output_size x input_size), and backward gives the three gradients. + +module Dense; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const MIN_INPUT_SIZE : u32 = 1; + const MAX_INPUT_SIZE : u32 = 4096; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const DenseConfig = struct { + input_size : u32, + output_size : u32, + has_bias : bool, + activation : ActivationType, + }; + + pub const ActivationType = enum(u8) { + None, + ReLU, + GELU, + Sigmoid, + Tanh, + Softmax, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // relu, the one activation the tests exercise besides None + fn activate(z: f32, activation: ActivationType) -> f32 { + if (activation == ActivationType.ReLU) { + if (z > 0.0) { + return z; + } + return 0.0; + } + return z; + } + + // output[o] = act(sum_i weights[o * in + i] * input[i] + bias[o]) + fn forward(input: []const f32, weights: []const f32, bias: []const f32, config: DenseConfig, output: []f32) -> void { + var o : usize = 0; + while (o < config.output_size) { + var z : f32 = 0.0; + if (config.has_bias) { + z = bias[o]; + } + var i : usize = 0; + while (i < config.input_size) { + z = z + weights[o * config.input_size + i] * input[i]; + i = i + 1; + } + output[o] = activate(z, config.activation); + o = o + 1; + } + } + + // For a linear layer (activation None), given dL/dy = grad_output: + // grad_input[i] = sum_o W[o][i] grad_output[o] (W^T g) + // grad_weights[o][i] = grad_output[o] * input[i] (g x^T) + // grad_bias[o] = grad_output[o] + fn backward(grad_output: []const f32, input: []const f32, weights: []const f32, config: DenseConfig, grad_input: []f32, grad_weights: []f32, grad_bias: []f32) -> void { + var i : usize = 0; + while (i < config.input_size) { + grad_input[i] = 0.0; + i = i + 1; + } + var o : usize = 0; + while (o < config.output_size) { + grad_bias[o] = grad_output[o]; + i = 0; + while (i < config.input_size) { + grad_input[i] = grad_input[i] + weights[o * config.input_size + i] * grad_output[o]; + grad_weights[o * config.input_size + i] = grad_output[o] * input[i]; + i = i + 1; + } + o = o + 1; + } + } + + // The fixture: 3 inputs, 2 outputs, W = [[1, 2, 3], [-1, 0, 1]], b = [0.5, -0.5] + fn cfg(activation: ActivationType) -> DenseConfig { + return DenseConfig{ .input_size = 3, .output_size = 2, .has_bias = true, .activation = activation }; + } + + fn forward_at(x0: f32, x1: f32, x2: f32, activation: ActivationType, index: usize) -> f32 { + const input : [3]f32 = [x0, x1, x2]; + const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0]; + const bias : [2]f32 = [0.5, -0.5]; + var output : [2]f32 = [0.0] ** 2; + forward(&input, &weights, &bias, cfg(activation), &output); + return output[index]; + } + + // L = g . y for g = (g0, g1): the loss whose gradients backward computes + fn loss_at(x0: f32, x1: f32, x2: f32, g0: f32, g1: f32) -> f32 { + return g0 * forward_at(x0, x1, x2, ActivationType.None, 0) + g1 * forward_at(x0, x1, x2, ActivationType.None, 1); + } + + // which: 0 = grad_input, 1 = grad_weights, 2 = grad_bias + fn backward_at(g0: f32, g1: f32, which: u8, index: usize) -> f32 { + const grad_output : [2]f32 = [g0, g1]; + const input : [3]f32 = [1.0, 2.0, 3.0]; + const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0]; + var grad_input : [3]f32 = [9.0] ** 3; + var grad_weights : [6]f32 = [9.0] ** 6; + var grad_bias : [2]f32 = [9.0] ** 2; + backward(&grad_output, &input, &weights, cfg(ActivationType.None), &grad_input, &grad_weights, &grad_bias); + if (which == 0) { + return grad_input[index]; + } + if (which == 1) { + return grad_weights[index]; + } + return grad_bias[index]; + } + + // An empty layer (no inputs, no outputs) writes nothing + fn empty_forward_untouched() -> bool { + const none : [0]f32 = []; + var sentinel : [1]f32 = [7.0]; + const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None }; + forward(&none, &none, &none, empty_cfg, &sentinel); + return sentinel[0] == 7.0; + } + + fn empty_backward_untouched() -> bool { + const none : [0]f32 = []; + var sentinel : [1]f32 = [7.0]; + const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None }; + backward(&none, &none, &none, empty_cfg, &sentinel, &sentinel, &sentinel); + return sentinel[0] == 7.0; + } + + fn valid_input() -> f32 { + return forward_at(1.0, 2.0, 3.0, ActivationType.None, 0); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // x = (1, 2, 3): y0 = 1 + 4 + 9 + 0.5 = 14.5, y1 = -1 + 0 + 3 - 0.5 = 1.5 + test forward_basic_case + given y0 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 0) + when y1 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 1) + then y0 == 14.5 and y1 == 1.5 + + // ReLU clips the negative pre-activation: x = (0, 0, -1) gives y = (-2.5, -1.5) -> (0, 0) + test forward_relu_clips_negatives + given linear = forward_at(0.0, 0.0, -1.0, ActivationType.None, 0) + when clipped = forward_at(0.0, 0.0, -1.0, ActivationType.ReLU, 0) + then linear == -2.5 and clipped == 0.0 and forward_at(1.0, 2.0, 3.0, ActivationType.ReLU, 0) == 14.5 + + test forward_empty_input + given result = empty_forward_untouched() + then result + + // g = (1, 2): grad_input = W^T g = (1 - 2, 2 + 0, 3 + 2) = (-1, 2, 5); grad_bias = g; + // grad_weights[1][2] = g1 * x2 = 6 + test backward_basic_case + given gi0 = backward_at(1.0, 2.0, 0, 0) + when gi2 = backward_at(1.0, 2.0, 0, 2) + then gi0 == -1.0 and backward_at(1.0, 2.0, 0, 1) == 2.0 and gi2 == 5.0 and backward_at(1.0, 2.0, 2, 1) == 2.0 and backward_at(1.0, 2.0, 1, 5) == 6.0 + + // dL/dx1 by finite difference equals grad_input[1] + test backward_matches_finite_difference + given slope = (loss_at(1.0, 2.0 + 0.01, 3.0, 1.0, 2.0) - loss_at(1.0, 2.0 - 0.01, 3.0, 1.0, 2.0)) / 0.02 + when result = backward_at(1.0, 2.0, 0, 1) + then @abs(result - slope) < 0.001 + + test backward_empty_gradient + given result = empty_backward_untouched() + then result + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // input.size() == config.input_size: the bounds the layer accepts + invariant dense_constraint_0 + assert MIN_INPUT_SIZE >= 1 and MAX_INPUT_SIZE >= MIN_INPUT_SIZE + + // output.size() == config.output_size: each output is one row of W x + b + invariant dense_constraint_1 + assert valid_input() == 14.5 + + // weights.size() == input_size * output_size: the fixture holds 3 * 2 = 6 weights + invariant dense_constraint_2 + assert cfg(ActivationType.None).input_size * cfg(ActivationType.None).output_size == 6 + + // bias.size() == output_size (if has_bias): the fixture carries a bias of 2 + invariant dense_constraint_3 + assert cfg(ActivationType.None).has_bias + + // All inputs must be finite (no NaN/Inf): finite in, finite out + invariant dense_constraint_4 + assert valid_input() == valid_input() diff --git a/apps/website/public/widgets/nn-backprop/nn-backprop.t27 b/apps/website/public/widgets/nn-backprop/nn-backprop.t27 new file mode 100644 index 0000000000..9b1fde1101 --- /dev/null +++ b/apps/website/public/widgets/nn-backprop/nn-backprop.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-backprop.t27 -- backpropagation through one dense layer +; Source of truth for public/widgets/nn-backprop/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-backprop/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/dense_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 19 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets the output gradients g0 and g1 from -2 to 2. Edges are +; backward_at(g0, g1, 1, o * 3 + i), input nodes backward_at(g0, g1, 0, i), bias tiles +; backward_at(g0, g1, 2, o), and the loss loss_at = g . y at x and at x with x0 moved by 1. + +; WHAT IT DOES NOT CLAIM: the layer is the spec's fixture (W = [[1, 2, 3], [-1, 0, 1]], b = (0.5, +; -0.5)), linear; the inputs are repeated as K_X. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_backprop; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-backprop"; +pub const TITLE : str = "Backpropagation: how blame flows back through a layer"; +pub const DESCRIPTION : str = "Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers."; +pub const IMAGE_ALT : str = "Backprop card: a dense layer of 3 inputs and 2 outputs with g = (1, 0.5). Six edges are coloured by their weight gradients 1, 2, 3 and 0.5, 1, 1.5; the input nodes hold 0.5, 2.0 and 3.5. Tiles read input gradients 0.50 2.00 3.50, bias gradients 1.00 0.50, loss 15.250 and with x0 moved by 1 15.750."; +pub const HOOK : str = "With g = (1, 0.5) on inputs (1, 2, 3), the weights get 1, 2, 3 and 0.5, 1, 1.5, and the inputs get 0.5, 2, 3.5. Two products are the whole rule."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/dense_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 19 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X : [3]u8 = [1, 2, 3]; +pub const K_X_NUDGED : [3]u8 = [2, 2, 3]; +pub const K_G_LO_C : i16 = -200; +pub const K_G_HI_C : u16 = 200; +pub const K_PRESET_G0_C : [4]i16 = [100, 100, 0, -200]; +pub const K_PRESET_G1_C : [4]i16 = [50, 0, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["g = (1, 0.5)", "Only output 0", "Only output 1", "g = (-2, 1)"]; +pub const SAY_ASK : str = "How does blame for an error flow back through a layer?"; +pub const SAY_G : str = "g"; +pub const SAY_NET_LABEL : str = "Three inputs, two outputs; edges coloured by their weight gradient, inputs by theirs"; +pub const SAY_NET_CAP : str = "Edge label: g_o x_i. Input node: sum over o of W[o][i] g_o. Pink is negative, green positive."; +pub const SAY_GRAD_IN : str = "input gradients"; +pub const SAY_GRAD_B : str = "bias gradients"; +pub const SAY_LOSS : str = "loss g . y"; +pub const SAY_LOSS_NUDGED : str = "with x0 + 1"; +pub const SAY_NOTE : str = "The layer is linear, so moving x0 by 1 moves the loss by exactly its input gradient: compare the last two tiles. Chain this rule layer by layer and you have backpropagation."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/dense_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_inputs_are_the_spec_fixture { + assert K_X[0] == 1; + assert K_X[2] == 3; + assert K_X_NUDGED[0] == K_X[0] + 1; + assert K_X_NUDGED[2] == K_X[2]; +} + +test the_presets_stay_in_range { + assert K_PRESET_G0_C[3] == K_G_LO_C; + assert K_PRESET_G1_C[2] <= K_G_HI_C; + assert K_G_LO_C + K_G_HI_C == 0; +} diff --git a/apps/website/public/widgets/nn-backprop/tool.js b/apps/website/public/widgets/nn-backprop/tool.js new file mode 100644 index 0000000000..8f5522d17c --- /dev/null +++ b/apps/website/public/widgets/nn-backprop/tool.js @@ -0,0 +1,39 @@ +// nn-backprop/tool.js -- lesson 19 of neural-networks: how blame flows back through a layer. Given +// how much the loss wants each output to change (g), backpropagation hands each weight g times its +// input and each input W^T g. Every edge and node value is backward_at, the loss loss_at of +// gHashTag/t27 specs/ml/layers/dense_layer.t27, compiled to wasm (./logic.js): 3 inputs (1, 2, 3) +// (K_X, the spec's fixture), 2 outputs. Words are SAY_ and numbers K_ constants of +// specs/widgets/nn-backprop.t27. +import { backwardAt, lossAt } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, el, fmt, net, root, say, source, tiles, tone } from '../nn-kit.js' + +const X = K('K_X', []), XN = K('K_X_NUDGED', []) +const G0 = centi(K('K_G_LO_C', -200)), G1 = centi(K('K_G_HI_C', 200)) +const ctl = controls([ + { key: 'g0', label: `${say('SAY_G')} 0`, min: G0, max: G1, step: 0.05, fmt: (v) => fmt(v, 2) }, + { key: 'g1', label: `${say('SAY_G')} 1`, min: G0, max: G1, step: 0.05, fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { g0: K('K_PRESET_G0_C', []).map(centi), g1: K('K_PRESET_G1_C', []).map(centi) } }, draw) + +const svg = canvas('nn-net', say('SAY_NET_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, svg, el('p', { class: 'nn-cap' }, say('SAY_NET_CAP')), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const gi = [0, 1, 2].map((i) => backwardAt(s.g0, s.g1, 0, i)) + const inputs = X.map((x, i) => ({ label: `x${i} = ${x}`, value: fmt(gi[i], 2), color: tone(gi[i], 6) })) + const outputs = [s.g0, s.g1].map((g, o) => ({ label: `${say('SAY_G')} ${o}`, value: fmt(g, 2), color: tone(g, 2) })) + const edges = [] + for (let o = 0; o < 2; o++) for (let i = 0; i < 3; i++) { + const v = backwardAt(s.g0, s.g1, 1, o * 3 + i) + edges.push({ from: [0, i], to: [1, o], value: v, label: fmt(v, 2) }) + } + net(svg, [inputs, outputs], edges, { w: 440, h: 360, m: 6 }) + stat.replaceChildren(tiles([ + { label: say('SAY_GRAD_IN'), value: gi.map((v) => fmt(v, 2)).join(' '), tone: 0 }, + { label: say('SAY_GRAD_B'), value: [0, 1].map((o) => fmt(backwardAt(s.g0, s.g1, 2, o), 2)).join(' '), tone: 1 }, + { label: say('SAY_LOSS'), value: fmt(lossAt(X[0], X[1], X[2], s.g0, s.g1), 3), tone: 2 }, + { label: say('SAY_LOSS_NUDGED'), value: fmt(lossAt(XN[0], XN[1], XN[2], s.g0, s.g1), 3), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-batchnorm/card.png b/apps/website/public/widgets/nn-batchnorm/card.png new file mode 100644 index 0000000000000000000000000000000000000000..9bb331e1c7b9b354c0ff94d7a1c6f2612785ad61 GIT binary patch literal 48539 zcmdSAbyS>96EBD+5Q1Cq;O_4379hC0Ltt8@4O#5-+?MDcfVFiX!L2e6tT-aVR3GyXr9K1w*=d6;Th>vB z+J0luGvo1++095wb%T*zQ;DrzvS}6Q9evQ(cXdM)5FVyphq31k!JI&jAr4NaJBWAJ zT_|Xj4X`&Myze{Fy8jO8wdL36OG4m3Zx|R_a*V&yypnL>$p59u{y!r%GGfHOr;HPp z;<)mX-STb?5&E|x7~wc0)nm5?EyaboLlCrc`}V1cEIE951)RX_jM*0IO}Kx0-XxHTP>Daw%kzU;lyvlhxc-%U(%z==ab(2D zYHV`xjpI1f&w?TS4S_a*u0Z^s>H^oL=`6zDtt|dLFwYN5z)#^?f7!&CAVT_1E&vdFvw_54=w0Ym;Ke7X~U3gv$kbFJVQjX{X| z4gNXJNqY|CU%3xr1hA2Io0OZm^`ierIlq8G`2Xne+7ap7za@!7#Qqijr`jv2h=z#W zy8kPZ%Td>OI(Vm4{+#AEqr*Y>bNu7jUJQigGv?oa9cVCp>G!UMW;~}{&4Jz;A>mRftt0h=ZMMb&*=APJkZiwe_w>4;K{Vg z$yL){5I*16g~WkD#8mYM#S~}(M;0{gqBT$s^KrjxHbF&_H_UzRm$FM^`>vNUE*yV{ zuru8jE_V@dtDQ3U;F3Fyk*mH-AO$CGV5NzGkT%?Wu1 z&DGuX4Wd=3!wy1$EhoSx9D-w#8UvOj#0&>e(pGs|HL0 zXwo>!SjL#OFl#gGg=~JsQg}#gE0KYsGQX85C`1zSd>^9BUjCj2s_yc0UC_uUEEW`y zW%AuF*O45o5x8lyiqIUtcvL}1@jGe$ATl2bc zMhOox8+IRy8Sn_gGjl?A&c+pGTO*es_$MZBc&;=&{cwo}SBID)pB;3+*;mtCn>*2Ih z-tO$`8wIWct!An-Rxf^803S$RLUSjpp6=aXu7XE1p#8k*9Cig6pl&Q7z?!uZxiJrp zmBEv?^Vn_5+J}*$$KyE+8iQqNe?RspZ-SJ&dg)XC=X$BzU?Wj+mA)VpkNS`=ze~wc ztCzj&OoeEj79PPWG**OJfV+1dM%h#NlQQ4APt-zzpo?lLE?-C;Ibi0v{ z#A-H0S*T3?+2qy7G6k@b@hzj?)L_d)5e`{Vj__lROA_w7emIDTLPr( z>&*-X1`*2D)vHQ(#M!Hz0z$lbYL9n#(flAs(HJQsJ2SMG;pYb-`X0`D^RqGu2-1l0 z*GcwLq&)U>QS33yQ!(l5hJ0hK2iLjJVJgLCojqSy1lpC+%W6W#D@Xw5sEAY|lBPcd+NuOSiu#Vr5lPU`h6h3GkV#8{*MV zHUoo*x}P_q)L@;kekf48pnw`p2eqB!>=?M(F>;78Bqj{-|v9rMcO10C9DcWURxYtiiUb9cx!M7N_ zjr%BJ)_-i};ZW*=8NJ5YdSMWS)>n&~M6e*vdGhbLF`z#+8 zVA2h@qGDaH{3PD2W>dC0V_ak0yQ9_RnE*qk>5|)L|FjAci4^)VS`#vA_O;K^&#um; zoX5YOf+o5E>TxjXJa&djy!w!cb$%UV)g4-o7n{iWHrd?eP}9t#8rkUf?6FwZw{}Bt ze+p$Et^EQKr+GWL%W{M5rEcYZmT)cL16P|UZ)eI18vVeqU;f?%!ET-$e;0JJ_A?e+ zz$Ouqc8uLT`zE)DL_%7;(b6@X1!Z!8`~6z$cO%yxzqwu5?G#6WKkS0y*AvEc)g}CD zSy;UhMKQk1B%Uf(+ok}rxR3HDPVrTEii_xZRMfZ42t`SKS=d=dA53L&Xm2y+PfthL zU$_2iydu5NMW$4f6Qi6QKS8#d7}dY!RB3*eL{2L@HPA!>eQ%x4hrEq<>MDojRGV&! zCRUmq3|j6QcI|o2SDP%a0`|yLe!CcPxUV~tb#y(3jEByIm8m!fSl`T)YXfUoC8x4d z5<0xqE$$8NRm&F*2!DF0Xczhk05cSKf)#n$*a47Rb0zyVMu*geahZgprx%MD>Q#{~ zUXNbN_rD8F$s>{Q$yf>0c8ut>h_zIGU=cMxUzTpAk zf3Z322rCk82KlEO!HQ2faxwLbr&F7!lC2vgN_*Au5ApV^mMbyzG_>E?vw zKA^0dDh~XC>l0A}lwEZ?{#^!+!JIMPO@@9L(+H4xpy%;H#x*UI>DkYfODdn8~Ua-F4Wo;Tf=b zx@-J~Pr~y2duThq6patpYSOo-uDxVtUN|(33AR4C7g-oBUJ}jN@EpFabjqJht=^Qm zwf8D&1o;lH7z6z|uaFrh{AwOgGh4^v-2*c#FI1IJh;hcgv1?9GcqTI&bC~-S+_hMH zdiWsD3;O5F_onzvUlSAl43fC$9!2RbWJyxL2qr%LG7Vx(JT}^YO@$^WJA8^SyL1+T#eb2(kmZgBVI03~U zqQ>nEWU6RmG%{?ul`$}=?``ePf(H|0qPhUk6wc@qj7UjW4Oc5z-hILfu+n$V6%KNoF#d9#ZEi&^gU(g59IF5 zF_U%qM|rCTk83twR#xo`P$)A)6d-C=D$hzp#cZ$(2IL&L33#vTaz7H8u1aq@g$fxMa8LhVaNb<>zkq?Iu;|CJbj;AQjW6)v&|aVP;Q%(1`o?#{4csdH*h?JvEy$wEN!Y%z=t{EDq+3%;juvcw=aA3YeokpxAe$y{9aJxUSWxE@1cFi3w+`HHD0LzKBA~Z2#aN;z; z{)3|N+Y9Trm>CQaD*bI^U*8t+wl5m6P4Rh`QPX))2vLaq>5pp$_&m( zDz%N_c9Ok4Ty2|TF*?c6z?~9hH5s`ti&Lxff^Q~MDRMhtx%o=TWhYX5-wP8vliwAP zmhLq)rY*we7Gx~g>AcW|fK`9gFKCGVJNBXQ&y#8`y(TX-bW3S{e5Gs!*t&CHepQ^E z%5S|n2Ab-X7J7P>^iJR4y?mKJ)f4Oq! zt38s#?o)dnY30m-poq?_Q$PLj5@#WR?2Px>Vdmg8V|sv))?!H2i`K}JcTXFywvv?$ zEABAlu63#7_PnKXx_M5|c ztfZBWtS@J=D1Q{uT944nnm1tl#EKKXS!7t^CkQgZgC)w!F%*8 z^?6_UGk#x(>nNTGCZ@<1=MpR?<>IZIrrO20Oqur10nCH5W))_BaB49fJquH(5lCBF zf{N;{*}eMQ-sU1)I5-%IGya3g6E)vT=?uDqcjf~v+0Do%31g2;zm&kaBBy|*ieXZg zkz8oZ2NH4DyHlk&AIEDOveq&>>gLONvBhh~AFbZf3|lfd_)XpQMJ{?NOl&>6YI6}Z zAFtpp-^qvT|M`YF5mu)tM41nl3TG19l&U7)J`XHBBD}f`$G=i(cGe+TVI%x_MZ8rw zaW=NWs=}c@!Jzw%Q7})V18|d22)U%nU-#0R=D_D|TGQwHIu|NoGN1a0wnK{Y&;2Esq$DHYKLtQlkfwQz_&>#o^-^Tk{@htt&||*8-DXED3#c%(=xdc zyAyRIoPrB%P%Q}S;`MfNYWzW}$peVfF@=^h&05amGN%Z(To9N~#03r4q;6Hpeegk) zeLHG~odG&`-xe`BLT}rwUb`(NpiXXGH3gm_MT~(+ax^jmHpvuuti!{Exc6h*i8ez$a_kBsWvhH?I*# zET`^As>r+qh9=r>D&a;x?F4m+P;X3+#ZSu7mA1JPo$(V+dwA@CTP1$bpV{{*cyZ;C z8ddai@rq;iWI!$!?M#2Gt38h_nZ--61#JO7%lj`^gxuD9V;`5sxYe4o5NQZ*k2Vug z7%h#ul#b~iCSQ`u(v?$kECpHmlH@uT9}*W-$RfM5WSdA7Vst-n*=zU>O(zZ?GNhPJ zVb&#rm3^<{r?fw!8+n)v!g)V}5)a?C2bQo&HZj=&#&S7Wsr97?-nJO5cnFC6Qsm|x zh{4HL8g|UjEsE;z)tuo9OC7gqSwn}wvP`nnmDa=gNGfxD@8Y6L~u{410B2B55X z!@0>9E1%A*We0?$zOH(|e)N45_&uk^hQoeSs&-3w-AtF0;L~EpCF$Eek*+VBGl}p5 z+@DJ()|)++Rz#^wgR=uXX9g@`BUjWlk5pGwu&j++%h(>maKVm3OS8+vYu%^uJs|nu z$XQAIl+NBa>3Q4LqStXTki@7{xX|%bZcYI)gCy5SDJT7W&a$m5+9mGK=6DmCg663x z^dirP%Q3XeLc+3!8Cl~_IdaN!s>=M?<6S#jvpmpuYQ+u#9>bAjD#ny7rfT(g0|@O} zh1q<7t`dM_dBS$}%Qo3LnIbEWFQRt@N+Qt5eYiedV>#`2@oN-gHe7FP^d}@8w+=t5J_Ckf=yNNo5ZRvu|&Za5%HY&l3WNilpB-S8$@I`<@in^ zOwOV@5Wq5)ZfPSUd72V|%_}BTw|ft-O1I*N>-ShPaB->B3SX`#()>?#_@pxHo^KYK zGr^j}k~H82f6CSnFv5wBdnSmZ$PxpH2F+x)CS)boV3 z*unVXWZ?PG;^{S5(iNSlY%!EhY`R)HWQAg+lzUv6$=<6v7>Ph`Hk>?I8g4`Ej&W1{ z_Wy2wS9#IGV#ZEwr!H~f*V1NSL}QY5ENYeI`^f@NJr>BJkoVOll-X_g*=)U`IL_1K z5C!IdeNngl2&)(2^Zvn&D5=hePu?d>?I|Zpl3IUV9u_*f$p)Y9!=h+7m}{M_99&}( zqmR}LOy3dX$Ofvm65N=miERI3(R^q@7%+UfI?6k+-(#%f@v;}6F5elPpuMsJXEbE~ z)&&F80`uRm97F_(e@HN~5+DDC#edWN4-$uu>0{n>(Fz5*^1p?0@XM-s2@j&*^z<<* zH)ozA|4Y7>5ineU%Z;LxLHf4=AL`1c?VvxSYf^x11>F2zjQ`TfIZ#AHGe<6(U6Oy6Vud-8A%$ECb5f5gamyt00RMxd&# z8XziZ2Blg*>sttB(TFc2jK=;?Nhu%U%DHK~#;&rmt|}Ga;OY0Xe;eXc5c~HdF!8^g z;CuI~;=fN|{{K!=G@?ZM?}erg{_)B~H21B26e9r{vv~*L`tBda^7Xda>?IR*a)7mi z?)~=4M*7K=+32E!vORdj;lZUhIj!zGsdwYW`D*Hz`y{Rh_Uh$kcl%lXkvC4b^{#AS z5yd2X-t^DxepWZoFR(Lp=T!IVvAx*N->TuVOwS+I5ev=BW;}&a!Y;N8a*%$pE5n1; z8p3LLanOMI?8xOkT#V-QK*5vSaZ&02aA9FQzHyvVwUXYux+!$iiE1y41a|h@EWH1H z*YpHPr8yffJkLbdxfpMwlWl@wn8u28TyMFuh;4G&4(v8Ic$^we2kOi^pZSsrk+HO0 z04~5|MA6y;-&Fn2E^PDPw8!@}a6*9h4xVP><>#|BPrG2F^s)!5hkD=Y~!q87U3H7UnDbF`TxOj>s{dj<6}`Buz4MFniX1+iAy zy|2#pYd@-GWfwStu;{QyZ=m2DHJKBHJJ4S*n?uz zICeg*o_r1)IK67YKyw{agE6;o~piz6>P z)q7G9G;>UdqBW2}gR`9()BCO-Tdg&85mdC5Lr7+ZC2QDtQT`PECS z4HN&>=|1g9CZ!C*<07#loi$eGq_tEID}<>lAMWIK@AJB!*2W*$AnwhsvGNWz8oMTh zmpgyc-@Q>}I?ZjDwbtlHj`=NiFE8LQ(c;?b(xyOUTZ#=^M$#A$xt02hFs`upi(m+U zcr;aZT9V_&K#Z|Jv@Uf=cpWgXV&M1zpU+}1{;;G`^5 zwgM)mBBkcXkFq@gAJ~~!`N@lQL1SJ|jRZky*E<&JKQH1$jgz~M*1UQt({|29g^EZ8 zJ=Mk%im^0|1ZHde8QsZVQOwUW#nBA)tc4c)@$%eC;El#__fnEV7+BjQEQJ{{thR&S zjYp$Vv-o`G_Ogca;TmG@`0ryct?a6~I9fJJVC*F|7amdm5U|tq72S?KLVXV>$Ga_` zG$S6FpYDT;;ieaJi-{feSrvAK4lf{UfUSg1%C(i%iK$;{vjv%aZVt||9_MH2p6%b> zd#K?TS+3lpeb_wy!u5Svfe>}Yw(OQv@P^ddT_t3B)2eYO>E}imdf{U9hpP_Hoc8fw z<+}q=6J-}YzpbV8(>Fx+oZFkP-$A4b zFS=cC!qBVh&U=-K*v+HOl}|}TWR+bwuFBHhaO(S(7TlQ8tE%#+J6RLuTMo!M3q>@< zbbs!RraFh}bMe?UHfN57)2Ma-JEqIC%R%Mh%BIUp_x8N#ag`+FP7X_# zA1sj~D#^z63ajYlW1&}i%75V5y9l?d%jWP+u-VLT65r^nxF3E2m&$y=!ajMq8Q<`X z_&`L*BHFlD827$6G%l8SWrL<`@sAcGc#uq$?tKOq&&X8JIB?)t!{yh@_u}If4*7R+S^LL}a^683YZI|rV^bUZQa!pOn zt?>A_`q+KbH^;+e590aR#&of`=~lV@+r(3HmldlvxNwQeOOMai>(_Xc^v)z}U(8aT z*37N3Tl&*^Hc0)M-3c7|o#$lebTi*JEl{@m@g=x$ki_k4N^-;HM;{T&@|f%+1qQxL1jhQ`6=&#O2Y zt~GDK2p#8>=BibiO)7_-@MUf*di9I!Wg-~~OVVTPhuLmpHUM1DaX5OfW zIrBz8_8yyP$(B3@jop!q+xS{c?%IM6S;#$?n}lAX2Jr?qy6<1Y&UNb!vr5j5^&o0_ z35VZN8%mW`l;m%#KB9-b2VfT!@OA`led}39NU*$ zZ)&ITUY`NGOQ-##h}~vKsRkL4*=L{@KYP_{+G`d&;#)x`*TP-E{ruc7$}?jj@0%;z zCHvTB`;n3&s>;}8rjRfFPc^sN1 zT6*)A>A9do>F~o<^mu;$!2CM@D1Wp+5UkUrwb<#zDTv-5&!b-sc|GngKKlI8!iQJY z=t#87(toj*K0iz$L7H+vluU?4%%^3Qnrc;p>C*3|9yJsdPIC1da;3KWa$SZQ_u=`r zBW;`8=!V_1X5-r#%j07!vdjB7O=VWASC`!=+QPT}-1)StxHK;{A{T$A2D|;7FNbQM z9k8k)v47mD=C`$h9P57+DBi62Z(tzF??&*ZIL#pWlllNQV~lw-B<~;gG^n{lbcgvz z1d|p|uh=4*KC<7g^_h!`zEmq;_0XawX9-zau#^mWE^pD@T~^rV<&NT^3%7Tjx`;ad zD(w5JxG)ztRNxQby0jLP>G=Yl3Izky-X4EhDMEn4zCt&$U==h!~7c)+yrH|4CNO zkq1(Lsn;6n)n3DC=y*aRUC>rjcR@FPjUJGR%i-)gv{(}Etl@Os*QkC63nQj#**2=e zhlWO~yVz2qv2vmLKg)TW) zlr<4O+~+4s=~`neI>=mmQl*uLD8vj|Qnk12mZI~LGS(2Z9X!|uQ9iD)o%hr6U^Qc9 zNqdlQZl(=L>sIlgO)j+{#3Ir1o>Rf^Ri&PMPxKQBd)=lm6Suy)nx88kU|${d{Q5yV z?|0pK7YSs|>ShyqSi7I+Oc?SVnw6KC2YGs8IKth3sHQh2eDLEIZ5O0+1FYX6|t&I zoz0Se3U$jYy0kN+XfKKkwn+$WNikMs0P+*-YNlLyH(8 zoOa%kq$KsIv9iuMd)b31${3aPP8ME;CiH=u`;5U|*S(tr)yjrK-l|(hl#FTb)?}q* zeO1k!=c$0*F3zrl>FCWJvz{pM`i#l<^_9YaUsKS|LuMblfkoS3`|AGl2XNSl$=*1? zf@}9AvNTbPvoa+vA!o};^uPOU_JvWF917 z%OqbtWRtQ1pUT+L{E&b6Ma6Uee$$+6nfZROc2Y1fPNvo}mtF;?GN^YsXYeq;bF#GV zZo>@5$>M*hqAsk~5 zQyC`?`v=@#|DdIG<+$riH0(b~fo+H~NV)J-FLy$0&SqZ%6XS7SE~;yy(j!e>Pt%^QP`sla&oj4@cE#jx|x_um~($l%VFG@q-CBk|>sg4^^ zC(uAgKh4E%f5K26ckO~>S(@|%H{&XU(`dIxq1%o0J44zEBVi8fnL+)T&wX13&x0&& zz#TDBe8F6v=did1GUmft%ZVl^jVj@Ba=rWMpo_HO>O#a!$>4g2al89kQwxKcEysB+ zJ9b{r6MRMmSL74pe(b40d{S@|lbCGI*)d)Tqz(Q^WTK~TVbVzg)S2{ozhKw1QRc*H z`sd;3{@X-OeeLecmwBA>63eSR$lYQUX3*@ER>^pG>I$Iz)B{VwvC*=$IF@Sf?yDz7 z{AguE2myg~r>}8J8)DokE0eN7$HTF3t*st3;!2yDWG^;AEHGB=UxlH}`e)3I!zW2Z zq>6!Q(X+0WM>Z$M&)fJNWlYG}{U1-%#7ULn%uSDKGkpW>4#uz-!(!7h{I%n|vx6I( z1VlL>e#gQWr%FaMc|D{_Q|^vuEBZc!q4N+|P6~up`gy-uYQMnl#X&6IL@`chU2QxY z)v!E~kyxlL*N$Ue^ZrN~@2y8>ZMwEg#^Yq-vmD(ClkY&0BHBF5>D}Abd2(!R3>Jd+ zu`UFpmr@Bw{sd0c+tapjbsz6F5af=5*-{3A4_%n#h1=~1t79^~InGOLu?OA|`Sd64 z^3xA?uetE#$J)MKh3=K9F^h;NK(8KS+Uwj3#?7pO8I(dTl>Po&i$fpr?HymhL@(`( zik8=is}YkfizD3Va_HByM(RPYh`9AW1UY?ej>~aiu|3%bEghFrh-)%^4H+~sLPOd9DmT6`g!y-cl7XFs zZ3R8H{*W7K6In=Po8Tw4%)og`@g zOp>m%g-&;}Eslm@3d?;I=qmlG=yT%_aeUE-`<06H4N1sQKh$7W6#6?h#>KnO_r73B z5g(cN`A*+MD^!d@o0|C1!(OX(lF{PmS;GoEJiO@EmBU~;qsZ!bwEC)1$-ZaohOmIO zn&wn5L{zFa9^*hvxVJ#w2oBcz9Mj9dx_gCOmY&gG`FPMwy-%MTfuN{PgU0Uwu&8kq z{nGX0L=>;J;1Jw?Wg1y7ALKN&l0ad9G8M8{=_dx+oIq$IOq4t3FmHZ(lm|@+d!3v> zipPjjI$xUMESJ~uUs{_rW~{zRv~J8EE-%6hzBosX2(!tR%{D&3`S2UcpR`vGU_okC zt5cP4yKijO568ozyX|vl71Dh@j&n&6-O=C&mD5PBe$H0JjH#qvtqev59RKZAqwy@$ z?ozggUq|7{yy&7)DYYSsM`p4O_lSU{^SSfe8l2Zv1J>QxQ*3R}J(c5~;YT;r$ai=~ zOYQq6>f*M#;yvHtYg?Nz^E;MAJ{iidt{cZu?1HJ# zgm?nT5=~YYU-p8PF>a7z_^4MnVLRIa^uIpIGYP6wkuA8DAU|ZzfRmLOx&$t}@UfKV zHPD?duJ>xoO)iT0-qw~i1pBJ?TmGOcW2nmDf6`FM^lbsA6w8-X5t}Hc`cD9?u_N6a zI|IAQV>~P61RIZ=3mCn*BkM9+;KQ~@93*=U3kvL$_-h51y8DH!dxois%G;y*S#F5= zxmOvshf3dP$ihx?zs@Gaqb{eQwm2d-2_(ahN$rC2j+rTyYi$*W6U!F*lFt-h-jVX# zUk)LO;va`T%A}LyvI!dCw^20CA=>tj+;#;D3Z*nf@~`UPe!gjoxP)s>3C^4~zeqo4 za`JF)Q~KFqU-{GO_knypP3V35QY0ZMU4!K@q$;VcjxYby+&aG4V;RpzvXON{*UQcOz4x@?R{#?m;f${x}&m0>9p_!1T&UfAyD9gVrN+qeGk( z#3)cr?}z%}1mIJ_Q=3RgCNG&K^~aHSj@1I6ZEzye=hsAtjD8EdOqCrr;m4h9eBroJ zARyp#?jQL$&EAaHp8OD}UTnXCam*bmDAD9E&JRxcUL}Q4GDMd zjwBfhs#06b*(?DV9159v?F!MR>o_|=8D1t&h#!g>tskEXvI5SuLdgnQ z;MWi$SD&Vh05y|8tdbcEN#WP1nuRTn&-Qc1g`Q4>3K%UJdRy9(h~w?YZ=ADdZV{&eSp07vc?)I@jj+ZcD99e^Km1*pT4BY`hwf$m?bDd84s zBx}-z+`c&R^s!lp+ShfvUv124;^Q3cJp1b@U1)3VBq4W%z4g_vWmJeky~A*SL2Ss~ z+xp(8?tOofD&{G>KV+LoQSdN0v2$HxIlr7ICrFxZPsR-mIxw*=75k0D=lXDkk}nL( ztI(i33SV8(XE7;e4pB}cbeQXS-{{_tsK9vlGg;$F(CB2qSS-Eb^NAb?cG0e10ybVTGAyIOdT4aAUmTi>OImU@O_v14L^G~s>O zBVM8D^NG_o6`b}-_npgK&ZqK;{uj-CQk)NjV@ciZ#MqKBZExI-n_u_Yzxsh!c-toB z?y{efoumvB_MQrTIMD+ahCCFHq@I!G$t~C0o=1B}WkGnaEUQOF+*w*(GaT!UE9CfG zS?nI*ouBuEiVBB6)3Y1u9CqhNPbfCQ9H$G)f(|KQ<2I4d2Xe^4 zp0jzqkLI14p~^`S_{W`UcH4FTgSw-mt+cJF9kF1poTugaeC3@e8)O%%-`7#U+NTlG zuVOSFP|Lu1D>qTr%E-g+{IoZ{l1b;0&zi%m-Yq}s%<@~r=ZrI7e)y2tzPacoZ7;mm zvyw4+_8VB5ZlKw3zhUl5t^OGA((X#*)7MHcQ_Jik+=Q z^`q2!OTB#UoR4nu!YrkY-4Vl#nXK`CSS`lWw%)U2u4bJV#*Og*G;;)lzaFCx#y_u? zHw)zdISF$L{J&lm`Cq#0|I>w%|Cgn{eZtvP`$l1slx6jaiyb#jmhO8z-W5IR$QoZv ztk!~tfG|7e9{dhFbWk#vsQ+x+M_6Nvj^g)M@p%u|+|)qKIX>qAIC!3L1(cuPTbt zL>-E)3*?4STZhj!bJA%7Au5tegGO{7c)Az##LN1Fug6UdM+%umD#ogO$U*V>i^;We zKd~>pCCGzrb8i}qit`)Cx+h3kso=KA^D`VDIFMiIa{~VIsPttty9(3vLXlf22!62H zaWr!6bH~TW?qi}P8p>FKB0J*R-7dFhuY$olo**{_s}~DvWs&J8w^!d29^$A*+`v}_ zOvM_JH=!Xc7k@VNY!Ny)ahWI`ft#l9!b(RHOfluKW@Xf;`s2ayi5^M5#bK)afpF|n~%E`H$_lkxejxX&LZsQ|k ze?bvtW)Ti21|tp<0#2K>Ub!{b*+K8jw&i1n82i1r8OLDIEe zzdpgf>gSzisCI?-*B>IeQNnK{G35k~9V|DA4)<9Ww3?vW7I0HDUAehUDhL80rH~go zFtqEpUF*E-joRJ3Khig1Ni{foWa^(TO9)5YdNg=V`;1a6^7rItNk78H7T5-D{AK7f zHRrSFC;UW=neZszd5~zF5XR^g*H20jB1o{c%C(NJz*E3i>>{)|0M+K9h5d6!?w+fz zEn^RfLFPgg4oGgw!j;fJdecQ2Nw*o|nB;)RVo#(!2~R`A&a>l=QQ8r~N%(2pHT^qx z0NZaAHtRXpRARcC@1Oh%#AkkAJS2Vk`923@+nn|U6c!NcK!{_e%?nGjc0pW0|CZ6; zmRZxeVHISCPxKKr4M8IsHNRraCKoaCbM-N#_)E@NeSt5r5D#J;AVmk8E#xB+gnnY( zlu+;qBpTJOzg;{(lNE3aSZ^|o``8L9DI!qpcks%Z~jj`gO~#d--Ol; zJ*reFP(K0}J+U1It56`P{6FsI`3!i?v!2fjA2v zR>bIVBBegWakE?X{UFJmOLvGNGsi&s_05l(XC+jr0rz*HiNdYK#V63!%N7&r+9RxK zMdzTec>X<38u4oyZ0!YxK2$x;+#$G>MTB$h2`M$H`g2j)LZOGnh|~T@jIT@VYlLw6 z^yt>rAlSrOdXavso)wMkm~h@%Y+BSbcuVsG_o|ZiXL6D3uv&3WQw~#q;r1OCcG}mW z!zJqa4f$ikTbmSE+8SQ@)$!yG*Rb9H<>jM&d!^*rua7_Y5%gBr9oy<7w^qmq$vt(C zNTS=o#9tjrs^_)vY>&eE-JRFMiWq4BEa7Hd=%%Bn((Od(l|FdE8`6=}9HgP_?#mT4 zSA8F~!2OP7J86*m6*o$XYn~*;Xv=%!3lq7y$TrENGT@^1`DFn<)Ld@fFYAI}%i7X+ zG*cq-uEmoL-96iz4H2SRZDN{DdLbis09j;I3U_ftzS@d#QlxQ3wv5xz8Vg6JO#)Yz z51=4OknTyRW6w19;c&nnTU}2Q{x^I~{XPPs9W+v1x9YX9YX80y2Wb zP$gRU`6DY+C20Kd^;G=HIK4t(u>sr2hy|A9R|Zqejvh(n(N3-QDD2qar*9wbLf1_a z5>s%knA4U%wblbir^*Oex)8=3((2<%c5UVm!UA4@MEe_`9g2NCfz(u#Sgr~P&LUe^ zrjlsvC1q+}`Lb~@!+Eu2eYk$JeF|~)3;?rt?bZx?z4e5%qQQ@(+?n77Hf&wE$m61X zFma^ay;%~W;mUdxF>s&cpc9{Ijv#2-(lxJijH}STje~JhaThzxi-JpO0ISMg?gzdD`zT*<8CB$9rRZ-KOc*-G)+M z=?YWgeU6S&)C(F;d&ut=IN=PK6scw$`Fi(vR66xP)hiy9%Z0C8q?&MCHiSb+|3Ar> z_}`g(@&EU_a>Fp%rB?3_Rw2c4gq&u9t6x+nl4WUx03DHm!{G+-`J|a2IECH33W~?R zfN#d3&SxXvj`Vp^Ko>{Rpeb^3k-VeXS-@K~|C?WArSIUZC`s8|F1BRP2mlMIpPZ3> z!?wVhiFdB2pnO(Qieb{2&CD%czQ zOS*JbnX7VGM2{C>W{w?K2F7-T0#YK+Y39H-4aCvdgI^lE7E0L=QxyM9}=$roSIL3 zDkTzC=W*T4$?Xvrr|5Waa@oOA zD@s4Yn7m=CCwXblQ1HB@7L%P)@DC7hz-Uapmbd>qXO_;SvDD8B9DaOoVJQ;KHHngI zPLwNGtHQLmp1)Jj<8}5(@ZgWIZOs&v>rmf^UhBp8-y2ueKc@c4Ikn-3&8q~DPbMc$ z%*-CTa(*6!R#-+p-)|g6hmxw5dL7|JSdSjiCdrff>n!im&C=R@UMl@zSy2CtXPcB@ zHvY|=^sY5FVfM)LnK%kXA8LB|i2=UQYU-O&brf*XJYmtaoQw#cje%%Eno2KHE{HF* zQjZgeB&aR^Uu+J`Mq|!6d*Y;<=N0J@zP`wk2mh$K{%t}FuE?n;qY0(n+ zwELW&C%i;dHdbxb^?2?Tvwcn5e4eow7al5vGX(@_G3>FW1qFtk*xq6pzHS#gi?Tx>w>QbHX_*o6s^R{$x>$=i0$Qq2} zUXRTvB)j-xPM1yBNT8Q1YHeVH@lliUDEzd-D_fb=x*MR5?b(%@7bSt$X&K3q2B4Voc9L2iVOKl|YWFGm$t zI>aco#;PEEQE-ij>fyOfT`~t718KZ~$+j0DFNN3fw98+_Pc!;t#p?5sp|4+0KQq(S z;dr5#Lx78@3;)y3ZXJ}C#zZ7?%daVM#wLXN5}9zzyyZvclQn}Nb}1A6rrBm+fRhw4 z4$cmP(zy6SD1S*5pcW!&{EBuIF4y_oirGy!C6{M=h35*YYUB(%@O(Euu(>%1)#ZmXY%0w<=jqz*7rE&OEtQq*}nCv#cB%EKJS&S^x3-wd3oH-n{h6 z)64g}(14OoS56SpeLh)(rA)6~LV0&&HCX^YEH=g;+UFT>%^BUC$LRYbFmR456F`nF z`dHJ5pUZl#{glLLAf3bL#ltckI%90V_+4fJ^0+{2t%*O6b4LpvsNPG9)cwz!hk>=TxP(eH;5OAtiIA?NH1B zWb(TMmod1!I%x^*y{l=~Y0t2*KAHu?Swllo2Xtr&KqJM*DyEPl$a9PIjL-!cOhWaI~26E}u2@I;5 zFW0_nyG8tM9i|!qo^5%)DE--RDuipdZV5se`Gw;R#4f}ez(kHe|J|-cK zXK_x`TY?{%OW$pAu#KsDF?Wn&pC6>L=44^d*jB`ul`ZgS(TM*<$B&XXF1{V z*v(zWJ}TCM73c$J0Yb5kR>y=N_s2U-e{3yi-odA{le#}F`EMl4lK3{nb-B(X;pz;N z`6?z(WOdcsZBv>qb6E;4`;3ev^bYHGd0sge3Y}qjy?fCn#Ui9lV12Fnv!nASo4=)I z)39moT%f-6MSnwlKd5o*2vrZF z_*q)~HzEImen{7)K(gZN^z)pmG*?>#iK^R0^MuaC{XLoor~3G7kD29fHF+;k(LF-LHJp0|%c!1-)rCmJIcw zv9d1zGC;VTO~g2iuu&+ZD<&syC_T|Y70eE6#)1hD(rk$@QFU+_QS#sE!?#X_ECSCn z(^hPn$gKMIu6IX?__vAAgr*3h80(Dm&%zt)+zJTxMzpF&stEPqxj5k%9|1i;rcAtF zO}!)V-%h|aBw3#fR-Imn7qNhrq}Lk#{YQ9{wA|~qJ9i{4KAzccCBMxOD3LWJ{PSf6 z+fBQ8_!Zo&Mr~=xQN#;Wq#a{FBu9%DSPxMcgxvLn0RtK-O|)8ssteiNg@0%y+02b)OP`V1ag!MwF|;!rbf+bw;;%ZL0y$8nQ}3 zj|9uk-DQIZnsf5%6t&ad;Sms6*W@3m@_rxsYSyCH1D}RAoM2k|@ck^|iN)_%LH)7W z(u`|O(#J~{f906AovEM_7D@}mCii|JCfSM#+h$_a5+AqiecMH26P^vvKD#89vZ;d* z72TOdj>W?-J!y@jbgBeDeswtb2sCZqSAZk__ml|$uA!q+6_ znIGBlEm09IjPA`@pa}c-SS?r&snM4p-ee1P1olOSxxk2e<^F<*QHceNc;z@E)4iq$ zl~71cN_I`ls^|H){Z5m6Ol}DY?%9MyW!icS$qIT1CTM4Qf*G|FN_`-OQ*5;5SdQ}9 z(Ny)0rLnyVxo>32)AgKqkt(b})Auz~Nv^dCAB+>SHQ}PRizZn#GE@}bE-c;TQZ$tB zFKAzaqFRjSNqmN2ELAI>>~bgKw@ucBHC38SjGHQ`^Oemec8FOYbLfay4IESzPExvSyY7+~SC!4?3|anjSo7XBb8pRO{`ak%G!`AX)RoTOb!8jWdDijqK zVs47VO={+x9ZykpwOJJgUWoWJ04vtqTKgY^=2h|=AJZ^lUS1yp0Ya8`a%W$B^=8SA zH*Mm@%er1v$2XO{6z#uISqd$%t*8blYzm0=9x-dQCh8qjT?@NZ))6=n>WweVs$}v+ zW2mkIsOu@Jc-jUA*8&&s?qO;`qtp~6e+35eCoI@_6UDf&k~93nJUY$7z~r z+0fN+1=QVhV_G9%ITpw5eT-#T75ZHX8caWfD@grO4u%Cl4u?0-M6&B}zis>O@nr@r zKlpufgBx{OTT3r|^71T1%H$pkEyh|-u2%#mV?f5|GEN-9Bcz8^*DFq?Vu%Yf?cOY! zGUkDP>E1=ovtqD$()%PZ6|N1fmIlXBQ%>{Y5ZXNM=^m zXX)lvzMT7G;m=l357di1+G2b6#HN$w*S>9}ECbU#y)EI_fDKDoKmyAys}h$pR9miS zgwm^2dnI+~5E-zYicsigSGl!ap+i(^$s_Td?EX|>EfB{6(UEG3g{ov9h%t0o3+!)(sFw5y_%Aipk@v7sj%c~QXInNTX(0? z#GS4TkfcCf_e8byS-B@@LZ!aN2v{chRDp8U{;S+Z>-4)sK105namFu#3duFqn?dPa_nA2rekJ_|!~V%ps?s4mN4jjh?C z@Hf|XsOabiR-XriML1v+%w4^OVrFfRUVFdX)l$xjK_4=^ZSkN+$i1!`D~QP zL}mmT>kD7-1p4|MNaGSbLSg_R!Y&}(0GBg9v`Ttnd~6)wc#nFg~a$WfRwxOWzH&vReQJu-=iH1 zr1mzkM)EIYVmY@ijm^vy6r$1k#Am6mZLBXMxc5zDrH;>ue6Z2RS%b^x^61^rn?_>2 z%N&|P2xc#5I7E|uJ7LyYDl7Sv((t_a!SZ_kUY9$yl<32xCHUJ}5x=bKT|OU)jC6_C z!j|bEk+fe7O0Rs}Yc51e$6jPH{}R9PB0dllyx1>-ORDc>Q~GqlIOn1G)RW@Nt0JQ@ zaKw5vi1`^5T5Zx+#X3jX)pl{|o7+<;w6Ko{RuPc=87}Y}aI5{kdz9OgvBF@*uk81j zt1S>?Lmq!~MjI%;X!-3iW2O4-hbYo%ZT^zJCobe(QPskNDmz1sz)8hJZwG907N4$Q z5kNK=6$Z-S8-tJ$tVM%H5zB%gu=?Mh05?OW7Y#dEV8B3NDd*GBX&OF0Zk{iNbb z&*$zqaE0q9_g{?F4f+2$ul9dZ0Q>s}|F&ZL``7;@A@~2WD?X+s$^UCE;D50>`$;E@ zWH^@r; zCb2kvwvs1BcKAsk!!Bi(*=CM_LxL$}nHo7UPRf~#5sKs9xhME(tVp=bqP0REr8*cj z;%e_y^5iISIw%asxB5J9O3DIzd{n(6FM&fqQ`lOOa|U1#N7q z4v^p&Qh4UBjR0{yDyOp6o>5gvuIDYimQ+?s;e`&Vzfm-JBN8@woH~+{OVz3%@q6sR zomYEZX=1FqmEgPTUXke+Y_zGIL2mg>;P00Sn$R@w>|&Ns5=fK6`Gu?!D;iU_pt5M# zafY_a*7kGRP*Lz?zZpJc&eD`Sub0$CWihFqjk2?nSC~=m;JS_XlY73+!KVool9Xia z1eLgKDsyk7&^5@nN}3WIH)c%*WoihPHYG*DCk7}X#K{?VdRY!O#tx0a@Gp(cMa8L= zz2)-P)B7sx4pAya{WOv${peLHLHM}tzETYdlp|GWOhx#Q=BbHjLr4jGJ0(n(v+XWB zx*fZjc?B)E;La#fR`uQi2)faR@lTi2EfS<%@=V_BcE7EVF*4ba^l9+_xpXjUAwE?x zj%Wf-%sN;d!J0;nL;>3xhF4GC30KxMhX@Np*(-Y2`Pt+3@t3rpOE2p3cG+aliQLz- z4TB>Nu*u_${Y#HWot`wvSx&T_AFzb#VNzk~0YLw0HeNPgDrKcIsg`+*;9%fz1xzwd z#q_kqC*cK2MPO0c{`DgdfqR>DRi{poN|`M-JUiG}?O9~a6nmG;xkQw8YAWt$Ny(A( zC_~0jsikp51OS|)kP#Rh3;&+|qTB$?Pgk04VwTx9a8^&Q$nz5y`aP>qI@&oT^UZZb z;U9&%oQ0YCOiE$jG}N|G32W`LntXe|SR4`z`9=fC!ta(&PuDH^mA5eh6qVqDtC3J# zSyfe)V#!#>XIOAfJKLY?(4fOUzn<~)@Zjc&k|Eot~jAO_d(;^j3TtHPlo9`|v;rMiOI<3o2|@*T}=iNR0xI#p%L zF>F|idP%tSl@yQ!#zFQ%Gm{I&hmLLo(|=^7DR!`tnLZWrEY%1agnWkv-^qMSX{=KL z$w*EXGBlK8@w5e|7SEOGO4y(rStDQ}kTE=(8(iY7UmkIj=rV0|Tlz>*kHevBvs`|8jEf+eUc2U`=UL#__0d5%lpN0#lF~lSt&ubl>d;D7~ zITh6(K=Iqu4X!#iF(vpw6?F8ngzv_(DxN17+O=&&+rv^m@n*`ds|uh>K@IncN{i}- z4ygWhR?3k|pY()$a!fAUPLJbG8yiYk@~;bL1XdL2ux^kL{ogfPK7xHRI#h~OEmzP! z*^0Rh1*g%2rUC`TCM6NH)ns(5j2xW@VWA-To;PgH-jAGXNEyKOK5VG(=q6?5eA>4x7bi8^@YFI*h8UyE8ER!{#3W|LMf%$?A7Hs<{~x{cIz z*O9&q9LW${Zu#b`6>hYMg58iHJvdlXd)#n~S@G7|boQNShlei!9i)-(+e zwV>PrGD^xNOG?DcX3(*2nB{R6nDoeFi?tz-k_>jb^u#Y^nC_pk{#1mu+w4*tV4u$VG z84`g`#kkl z&A|mKki@<&iVMeIjx46jXcC?#gyX$c*mUNZu|imVBlVc|y{%1@W)ePi#qS_9bmua!_HJKVk$J)%^-ScMYg8#MER?Rizves-55*IW zz(Ma$ScP zrEz=);ckDI8Z|of-0faKy+(ybMIjyYD4Z{{^hEE7NpS})p>r0sk|pc@$W_@nAT5Ry z=6PxP(`d#w?pZR)xshw*0E<`rO6>_Jp9#BLkKg0K;7mD14xPk%Ehk{ygljToKnHa z0UJ7bj5riWdotoi_BzRoSV|@4^g_;A9bPH{ohxFE7~MDQZ&~N`2_-26^4mokuv9wv zacx-5%;;q63S9=|bb3zOK(41C z9W!wYL*|7q3d8A3A#7$Fk&?Uj+sQ`(lCQ$T_zK=*{m(1$0U;~&h|1V(gp$VLDH1G{ zP>q`KZ}eHY2GSz+#=k5)leX-$0~dnjcqJe_eezzOBWr}@hlY{Ji!nzGS{hUN)W zq*MOu@5JA$CXt5wNO;QAMp6pRk$ciZrukboW4Eq&FKtNE4Hy34u%*W09HopH0G$q#ht)F{Nu^ zT8gPtZkl4jFY<@NXs?Q=6FMhPTh0&1scNFvqi?~N25YXs9I?8Fs65yRZ&EmOf_Cd~JZ98v@^MgP|UVgA5L%+%M8>udAlKU+rxD zzh`@S37R}Ec;y`8u3c&FGTJ@PP zt762NK0#Dve9RZ)Z}Bi2S{12!jg&U~;t*tCC6kUi?-Ue~wmLxnvUGX&O1RuX-guc! ze*^pD>i5TcM5|R%z@*2jz_f>B`^q{JJXoIm6>@gOf8NC3@cr6daX#X=nR_ zaQs_tFUztok$-_ejtI>K6O#A_y>u)6L8@pQL{XH0oE4);kjgh8CPdZ^rz-RQ7FDId zq+ozrnws0Z6=vU}UeeGvXt|Rvn9~VKVxMuf^_!G(!n7uU4$+-raq?et0q*XehB)PP zT!cj~_~)n8#JNM8*O)qPuQLXbw?8zJN%pst=YDSb!UTTs`ZZ)YeZ`4jF6YHd&mhHN zX5~Yn`a?G5`k^WWpRhSD5bO@0M79$A0wzksSz4Q7{n7fkIbAtLmQMpaqiz=Z*6VBbe;0w?-T+r0u;~3FX z#Ks^Y;v^xzk2>@EP6!YI&<3lOE%%UOn49X8d>-_Ar@jF4SMr;04$Et7X>A5N*H&D# zpUxhR4U@&c0%oOT6+&U15^{gs*Mpj9j%;7jUydiX*kxtljjwc~gTmGx%SlYor;Ls2 zH#sV4mU&N~D=xX(u%`%55S__?Wplprc2P|TF|$KEpD_X>mle}B$qDY3LC=uiV_p?ag}{u&ub_Vbtnjs+TW{O&ub`TyA^v+ygOB< zV{+7UHsZx}n+G$Mw7c>T*%!s>=p;g4|5QYJrFzL(Ki;uIziXFMFl1JBvKz$m9zw;0 zU3d5fGDL;G+%NRKD@cEqCcN)gfc{n!8SG>iOiN`Ni0sEBhBH81#z?{YE;^uW;J5*Y zHXn|T;!)(`N7kjQ>f*x1Hh2k>ETTRgxUZvevo&8=z-0glc`konrBUa8y?<`~`V!#w z`m7hJs!AO$jG&x=L)-^AvP_%SlcH%*>3{2*93&lDumd%$UYAI>ET~c#7hu-9GUZHx zB7nc?X8T)Olovrc_h3m_c)3q@mi~|GBS}vKYP5(3H!KBacwHw@wE+K0Bu~=Ny|3v~ z_dvU@t5t`dr&-PWE4S=6KDcFN*6Hv$#!%ncf(Sj{>r8u}LtrS);lk#$ z;SJd`BlZbZOm`_&nGC(2e$B>O^~SYAb3RnB5ea2Q2W}2No%l~%-Dws`%gTLy5)kGi zZe)Yvg7&R;MTV*H4;{;2oLOpEJ+MjmB%R7P#v~o<_y8rV&4N_3zauCZD8vvtJ_bOq z9UAXmw~Hz)E}x%xJ^KXlDq(FOqwmO_Qk4GTgPLqr<+FdSHvTYSaa^!LN+6 zN?qHpopsJGX98Bph^d@DyK0sWud~pElzR<%=i+pZuvu48Rd2jm9x0Q{Em;|xqSg|f z1C9^LC5Gt|<~78~sQca%wRc!;LvGV`j)j~trHb7A4-J>t%Wt1j6yGJHDju(P+nQ5h z+k#EENt~HhOZCNYw9j#mcjPp+7nzQiG>)i@-hc-O({`v8|KLro*K-sUN~}1XC%Z)~ zNXaItwbGes?7pM{7%8l>!K%ty4&L3>?v5hVk;P8wlKpD+Z@plp3hz#jhR9pOUxLE{ zKpgr125U0=jpm%+;VvB(WejdorRe>3bUtI>@o4!CL3v;*1AB}ya2(eo3FGkE$Q9&c zsSJfHUF+J>u?dwJ{|)-sesfgkMvu0_604~*Yi@FzE*=J_^jm}^YK{Hf)^KdDwb(?d zQ{eXi0kgpuTV7wpXoRmUoqPwiQS9lt-5{+5QZu|Tdq_JFDUf<`LW4--Zqd{@D z?f47{%hc=sECM4Ci1fr2^nz8`99`PA@&53zYq8O$xl&x(x-(r;&;KSlTHZ(i z0HY=MH>RRQulq0Chl&gH1hj{wj#vR(5X6W!qG8&)ajKaP+Lp2Gw3uuY-=~q&TB`il z&egLn3?0~GE}NVE*jn9v_{=*;fYV`Qm4 z=4~aEk&}G&y?by2h~hQO9l-+8`n>E3{XfkTb%q4VsSTGa02fB|*mOh9_pcnbXS}^= zUF)@`f7-F9dO;K~D&6tf{~LHqvXQq8ArYeIK?g`RO5gni0xTj2 z`3o~B>bf8HGv!$u-6nKgC!JVXkd#?oS1!c9HIQdCulf&d`|j_BJCcx#xq7vx+YYj0)FOARN&f6*i$&GdFDr!0wBso&NsO{{;Cx2*KKAA{3X+E_ex#b0H4F0h?v zo?0`WPXELBb}}ne%NsSc?)(VXD~6L5rfzotGENH}36U_b|J0AORYFh8+$tVksG=?> zC1jy2ZAku00L$KXq*%_3Ht9&R?k_OrFTG{n;C3iZ8L7x}iFOyc_Hdd0Ilmo8Pm!)m(yzP%-(!~33$k4Jr=g&>&_xjU+Y#Ap!pJuw2ze#-L0*}=f!`f5Z zo+*GIxBN4RFJCv%#p-Fazki~LJ*X^ya%eq>!`fgZjScKjEUFN$`Xs;@&YK-$>vqq(81)WWjr{{e*c)e&ZkDxE`O4G=iCL$ zdmfTGABFF#3@y_2fTMVF4?MD^GD|uC2z=YVr0TuF$*rigc_X%9c?<2bGHV!mdgRhC zFWsJ99#}Vz5q}-U<&VmITv_q4#D!BRn=`u+E~_$s@q8qanOX_E57+U0y8q&BsJC!1 z)v>I;8b+)kBC53)-yfFsx==hD-kwhDLq1?U2k_1@J~K2t3nMt&C$;5qPu!7Q)YRDH z=eiqHR_R4(lxol?wN|z-snx%3{Z(s$x-<6DIK=?;t%ysjXjt&Fe0S8X^9akxhYCKa ze9W@)GW`TPN3kwIDk~V4dB5`zoYgJwnEl1#{#P2LbIWJudoR;X2${Fb!2!Ik z8I|eS;{<8@Z|^+3$?x>~z`Ywg^RFs&EjkKwod#HFy*3PI>^3T0iBXGUvLRuUX%+IBT{Kh{_75Wj7O)>y-|bhL`ab8>cIb*}^mR=ix_%@J7JC=ly7w&pR2nVmS7R} z7B`U3uVSZ}HMQ`BxTyBt#0C~a zf*WtNPWGRvJ=4)anbD)pOLvD_R>F@9CxvW0Id#{S@#ectcvWBFt1@<<$X?N(?SMZo+{g6YCT^9u6H8v*g18)ttX@6gg< zH7QnpBJPCYlnJG3;&`<)nP(OZW!A^gGGQE4Vs@uGv)Z^ad;O=0tvz9p{}JWWwfY|^ zACvZkwmf?Icq$tLykuEr6TiKJ@-hbcaFj2Li;!SpR ziZWQkX8JVil~^zgMsHn+hD@~PT9x_b>|eA|2decUy0 z_E;xueT>J+W^u%ekkn8d{LETWMMpiOL&9D3OmKroL_%V@5*-+Zyvz;qqVr5o>=52$ z^udxl~->8oRkkxd6UFHqrXFd$_YL)(@fWn>(T&wCW(c4R$kRE z-~Uv3Mg>bL#uu!7{`CtoWBhk=F$`r6^XUYTD)vdH!$+-K=dSPRfJl2F65M5h)*_d`M&qf*z4P=yh?|j-lM+gpK$uLDO~MpEZYycyrYjF zOpuf{iflU5`*jNBGM)}YHu4CYld#F^9r4*(F70JjTWp&!3@HNtBf}F|$6i^AV@au4D%MkBW%30 zxM=VE7@tQ_^G*w?rCtmaUz(js(_!rqagSDixb_b-x)OAnY*|RtxrC(On(dThy6&+u zy!U>)LzEr^OUj-ihg^1qdndIc0K4Kkk`-?gz}yPX$F*Jm-_4?KR8ggzV5hex6+i>@$2xpb>RCzY7BNe!Zc{Kn9imzEY`#x5QJ?L$utzUG@n<5+6t&TJ&_dYCDl z&%O=H@VndVfVMi9_0*CKZhhUpFuk@{Rzr1VZFMfub@CSCAQkwjw7g?&PhIp@w}b`8 zv|gueyzk%*40O-dFCAvdyfYl1dJv>+TO=pwI$nmwrRlPU6G95u27s*@lyo_oJtcNW zO!xVj=k0C*x3|4nuji+>s8wkI2D8#@;9JTbU{b^6_~g*YELK&Uzr}VRI_<4}wWg)W z%a6@*Lo6y$)@yT@6M?q7xa$4&cJTfAMXu8vE{}$PcSrZNC!^drl3^k+M)3AFo;R)Y zac7~d;A`;NO@a!vMa0vlm4S2p|JKU?Q$VI-s@KZod(3 z1vr;2v-%1BP(?`MTqi)HM<;Cfd^PZPkj351hkTqNDq=K5^OugQuI~B|K(5zmi4Q!b zp0|?%L<42ZW}^TRa#&4u8hP=YMaF~{G;c-ec~nsD84EjKPNDl}WTq~Qiaj-XmtJeJ znz^s0Krkevsd?)vBHw#z&cGLShb#X3rEypLv4AWsSqxk?YF_+@J@kivzog{k?cEt>8 zb+Dv$mh~D~ALCU|kdRBxR1sB3Xu%3amnZ6cO>yTGCP?I;2~>`PuE*YEoQwif1_Wq8e<%Sy||zGH2es-rLvXj_pP+(!Qc)J zeS-4(4Jn$^5sK0nVgP)HP|cSPheWyJa_cuk*wD3?`llxaXGP8=%elh_uAwE8`rwLffiOx}N)=@1eIj^f| zBFI(9E4ASyOV-v5n4)nUHU84F%iEQ-i^^2jsXYYa??u?(m%t^x$;9YY5t>_!>58E= zqbdoL9Mzb~mEe5rrJ>E+%0CuDty35cD-czbcR02z3Aq=qqU<8IRy0`(cWeQh3>M#a zX=vMzX86SK@0ZD)m?&i{Fb7Eg#Tv;LS1B7tPl9P6!H(7h3T9^#G(Z2n?^$iK7B;7c zdZ`o|2m@7P;ze_-%l8nIipDCcdVlZT{cFBfSHqd}Gwe8Jn`lm_^%luY54V~pSX}+0 z6hGCJHU%b)egig+%8u-QvO!arFQ`&$+LEyN`4?59FaB9*yPB}!fmPRm1YV} zFg>6`)QAxZlN{OF`38zTrXf8}Wm+THNAKTcrsM|uSsWVCmc1v~>sY?Q;k$wb@d88S z%kCOQMSYNC56rM8R?#wk%iLbRj2I|2KYuKtFokU4)ZX%x6k8gijW8wlvk>Whk#;Lh z0f^He>Xr6Z z3KlZ&+?Q5*-2+>CO1&=<%H+o^6PhOW@=!w6L@px1?vg`AlX7P`9ip1LC1j^sKKvcw zN@eCiPV%EYTP<6$_Y9y5g*@x223g6v-5GKm>=f9EVT`F+rEE^^BGv}RU(aEVYuuUK zV_dc%)v=UHeyT5&9@alOpr4ex-uF*!f?TCZssK6vonR7 zaVX~X5_bOI7!2f18cw&<@SKH2M5s1@;UapOdEGO|b(C20YeyTB7cb`cOVHZV?HK>G z46Qwwm1?3L*t3v}E3YxEQXji{Np&K*S)^5QHL-G}#Hwr51 zR+TQy9RcRJX6RDER8U(;f$W$ZeE@~naq<^n&Xm&8Y>Klo#`0N--`_fPoWIvwUH~_7 z&|&}IL&JZI^{fss(36sZ34#MEio_;CP-V5?@lCzt%IyryZC=N)p6YUUs6%}Zr@wWH zQk(<%u)JJRT?sS!A!I6Yrre}cE8T?7w?GPj$FM?bWtFKa8N~;$n1<+~iePD>9aOrv z)z2DvMY9^MD&N19i907H;keY1BhCwxWS2ic9Y^By;{BZClB}3fEt3$$C^$N5rKnH% z8A%|}wkXFiFYOT}P<8{*F3Clwxx1QzeT<(5nA+Zva0Eq%Ee_O3_tYiIaR8j~W+V&C z;+?dEkTB~r{B`gIf$-Vo{!m;;2E>m~Jd7pLPUvVKD*8N8xVpIVbn<2vN>V(<>0tJe ze_`LoDRx)JvyOE2E_yl?1n*FbLr;cR(%^xvh$rs@3s7ExSOu0VC z!XTj@$!6!hjpTJoqwr*p<`3~oH<41hc z&Ll}gGKoQ1SIqd9`(?#B+(Zaomt-eIq#03Pl?fW5LqoG_TCE%z1*Ur^c`f;>hVo;2 z%7h%Gwm{O{w2v<3-04&7GD(b+77?^Cq31tVet_Z)wBbi zRvjQX==YYk*)ND{tMoYL(@M_NTm*ng65sAhLsV9fq_Cy4YdaC~c;3M->2SNE9jfN?}vkdc^_ND7VD%wbJSqLK67VH zr~ZjGbe#p8@qr1gYC}I}TE4i?Q+#YFccm_45J``axcp^ctDwUsikOf$DCvF`>9b4H zkWbbb%Hr~nnzRInjD@{`!(>@x4a<-t@QNAIR@rd2)wmF7`ca=V9bBTTBkYCvL?W&V zk_Q0EFyyGnKyC#Esqidi@#p13-H_bC+wW2!qgCre7^I^Y=hBIjf1o{UY+8aL0n$Wd zdI~3hLONI#ud!EtW^((l?n?ZwKPf-hADo_^2lg91^OXzp@C_KsgqwcFp#0GB<<#ms zf)g0zv7!jSFk0CAX7ZC|*Fx%deloF*g&Du0<-U`uqjV7Z3&3vM8OzA%HuSf;_DZ`7+PG{(!}3`2Kz~cLvWNXIay}m zIApy&&J^rAS15E%y}st1TxpAVA}q&E8>>AvVtA)AYsUz$kn*vOxjh)D!5x#?$^LWf ztMqTY_MH=){FL3kbnu}jgOwzH5NLJ!qPm*e9P!>3WQjl6@~8#t?<=lj76Xi!LXBmm zFEyNo<$p3{|I%9g3`mAJ9X1(3vAted_iX69 zWy854BeOpE)YrLIwi%ISggero^)q8RFWqiFHr)l*V&V3QH*5w|=RpOY(oXu7D(iDQa6Tg@0*6f6S|n z4u6ce%hAk~>F%ZZwHG85sN?Gprw?X&E>FsXWx^z|<0&y?zwx_bw;02_)U!i49?$$6 z(L;4yC>fKXh_x&BdlfI=sd;cbYtd3i-=hBUTY$77*Vh|QHSJzz4GMvBItz$+VR3GD zZNuoq5c4r{X8yux^EN(i_%JZgBToW|q4(8BeWHM-HHc!>rZ=#g@h2z9ib7MR`s= zu}1lYGo?Vq2Zr2v#;_XT1r<3JQR7EITcuSYjp5 zbXn-YgvHsOrw$KKDcdyf6VI27985v>H2m*jHHBpXlj9CQG_m}l;*NS1MZeWo9r>X#Sy3c1%4H)d>F2n9!FZW4gu@%BTJD5CEaV6b*n1Kdp}Yy_rBDEC*v>YxeMMu6o%L1k<{_Ko&>X28X0&lg?9ESLt*a4y$XR^H#cB^ zAkPdX@{&slexFt!(53>yA)fgV9OJv|+J|rE>iJZ6CQy}kC}Hg+rW^=(=CrJAn8+=4k-N0pSXZoppUImbM>!?eoX!yE?UXJ^0ts^9r} z77C5|gTxLl=PJ9yP<1s>wbQOM8*MK6I9lYG;xmd_8o;RkI?I!3v2l|!#8K|1LvTtz zXLP=+rXw3IWzwXt55p1+`Glhdx{Z4mb)g;7EIni=K!1G2?PB)4k2yOd)&3lqv2x+L z8DWF&yD>7POvuIBCrc9J4m{(xtu1?xWzlS$BSK4s2lG3~7S87G)3-NpDg72Pi*uZM z;tx!O*u-F_z{}`)vk626n>aL(8h3LK9-Sz zt+3n9$3Rg+Hlb$f^7z{5M0hKZG_a&N*^7^rQw$aPh?MxlB=nG1VF$)c^ye}~Ms2#- zz{u+cV}s3K(1c6QE%tU*q(H38o?ayXkmbc(uEW*KhmpduIIl+y@=YB1KNrT9IMdk_ z{AX9JA)o^$ZlUzNg|Xm>(}&*~JbKHm*uBd~Zc|xa)ng!2Y?grh% zkXzSwC%9!KB7LS84=7h?&|I?_bO>4(7u(zA5}OT5A-2)l$GAC**v|H<3-?kCv?P&^ zft`01Md?m~zZY0Z(n0I3i4DeE0bOBGg17^f-lDR}v+UpBW@oiN8E1e?ayvG5$*_!>o{jh2 zTo*}bwbzrUFKK3Z!zBSp<3>d~S~#xtagg^a=p8gvFTa7M%Y8?p4}>0?;JZG&C$wqT z5^WYe!adY4PPUjq)MAxprjy`HsfskJt#>?tK}!1=dPm7V6>Sf!@rxj@slqSy-h?&u zMed(am`$irPZQ&cqC|3ZV)rygx9`V3Q58+P)^s~$aiA1R@7a~zs?}&~0!^ z_RxjDZbUi9A5qmASEYEVIgLSvrRICQJxaPW%KkVM4=A{a%bG#sE6Qt%vkeOwisT^> z8DN{3pgcryE(&fAk&tD`P?Nzs5${bWH$g`k#`{25=sM>mG$`QK+t*)fRbVz$Z9enS zD(nhQ=|tOr5Gf6DtTZmL{o;aj?5pb0@OydNY-BZY?JYL)Yxn4R7wb@rUAWrO+05i^ zHXRk&S=@jO4rP@rZ3Ww^@wVZDuOdW0-^@HO$8zM(`HQ!ql?1m1HzHP>`NfW4Y+y@v zsHKK}@=7xH-E?lMLa(amfg!1JC$m9LoNcdZF+Dw*?351afK+_RNZ{duf^JCk&k#F% zf4M*CZ00)Bivs-6V8aCWkruE?GkJUsT0%i)uSq{V62i@0G@Rvsbp$7hofH8vASoq$ z$yjShDT=NCDE4W1bi#VgiKtSV$!RXXk_y zjU*W>yF&K;IH`gg)U>u+BK_?A+Q#n95tp9hb(V5L{?3c-6q3z{`Nk>qJzeQmr#B;)MoAoI z!K=^v40%Zq)` zbk+NIRyyrhRc!OtTHTSwxC#p`24gH(w;%2_^6LCbYpGhff}JMe&#q7-XHhWD+jbl0 zQ{id6J_V$#j5DZ3*yG*qJWy0eOp%^WNW{w zVt3u+mPzlrVR&xjrptdVD%av1=Dok5w0v)PiqmyiJ=0vOVF3QqEnJs}<-4}$L)*Bf z_X{=Kx29O}p2Ch++l5GWF%C2);+XicuYv?P!lE3t2uZJl!_ylFH!G3FB(z(~TzVwmW^SsT95c6Jl z(0dJU0G78{a0EU_>LUMMnxcuwCCifdC6e%|6!E>1%5F83RbSSB_<}!ki0!H*XK`Gt z8~(#QT7rhWnynR@wXrt!^&@7fB=_56Plmm%zZ_M4f)v=whLh8Hj3EKdwcZ@X`!9gS z9D&_(3lZ-Q(VLEBRU}nq>?ClcJwB`id!+ry_g5gUa~)oVfBvtMT)@a|)?Fru%J7NN z=ikg-=$V$~Y5qyE1ZM2BBwL40oG%~q+C5d(yKb*adt{ig%@?~?FN4r`4#*B{5n zK?v--q&l28bD>O2)fkKuOC3A>Sf#MZ!SSKk%XVS1T>_cB-$$;8u&{4hyW@j_Hi#IZ z>BXQ#Hk%nHE20~U9#bs@qWw8Ob8&}CU3!}_Vw?W*jOrx>v&`igt!m7LEHX9mxHmBiTeEy=EZu6r|vOSO_?v>%I3SDfn$YgjjmTYXRBI`K@N zBxaqoa}|8^-fel$6?6((JBhKdP4rW$aR7PWVE3YruKu5~5b3TCo!eG`C#%Zm1%1k6(@^;^pgkDeC)-$c?kz$LVS|0M71Uik~XGyaH zcT_#k4x3qB<6g>Hf$+*0X-sN3C~omM!czEdDjcbJe32SgxM1CfoqSE%i01(>g_{e` zt8m>R7D*}xUPtwncWCTjvk z3>e<^oIbj!n_31g`W=_kT;u4b_C5YKpvPCCo0rBT%PeUX}zPnX)-e*;z=?DI8LFUBkw9{Z=LgqJ;hG%RN0 zBUVDj4+2hm(Y_9UR9!d_3#@oqK`+(qD1-6625ivogEyGUVMu%_h5Y*+DU;0Tq?2ll ztaz#rFLNU5ht-p1qn@>eI&ewUo{L^Sz1_R2#Fw!|^R>M;I_^S4gJsD}JC_v%yldFt z-XjEJ4}9D=hw-0DL+{?x5bR#*y=P;*O^5XTP<0f`SEIJye7^b`Ye0xSu=z2FyaklP za)#aATu*t{^=+Q=F-95^Sy&IBQqdDK+^^qhfR+@6xS2$<{yHv&mQiknasmIxCnf?m zR27imoZ*wWB4GkFu7%A_j)7yxw)RKqi1SrFPJ70;M%;s~I`I zI9HJkE6t1(G`d7m^cdWPT%WDjYwOkzg7;sJSJM$zm=hzkNqMc-gLjuJ&<>JZh0hsV z+mfwU0;jCxgq)ho=6*Xk`F|LSUHR1kY6`7bLxYW<7h8Zyn+|_rUo}yEKT6B!NYX?5 zaFIJJcT3k3Y?RfYBr6up(3oZ_C63ew9`|GzXY*PsxYLcYdtVla9fyi`7UOQ_xUic2 zAb1mWDTSd$+w;56fR%eqO$cRy7zFBbw_~cF5P zYae_P+H~3sSO+?Fv$Nd(Y>v!SRRkSiUr#;Rht@MD4CE<_|BIxgPd`^D zw8Ih2K~wA2_q6dVTXY{vx=T-bFNTB-Ubfvqe9C&y zx1akh$x9U=NIk1HL^Lx>7fPeppSAy)QwO4R@IS zITJ&GIj_I=wCnMigebb5sxE5?WPv8lYUiJG0GkvvyEs+JE3URpfLXr!e^^cp7ohAH zcz4bcVbJodfW^iP`?W4*YDxq6IE`fFc&7m;A~&J4Ej#m=uqAC&yU23&8p9|7&^a^3 zY@kve0?}C&>#{e^js0$mewyyDxy+&`GWHE+-;#uC9!o}s-OWz#nfV;nlFzW7vP$!e zkn6CCaQyTi#7S0}aR(OwsZP&b?od(Z@yTyo3Ms;B*F{il?INVuYQ!0e9SBTD9J3e0mhI%^X(>A0GkB}iv`bbMd=6_D~34=H^J z*Fh;bwH?WOETYMGeuqwa!;@%*e-kRuTv|gd25^5kSnAePAY-%tVO%pP|GnHbNr@CX zbx71Ld%UK#RGa%t<+3&T$6?}+L9Vul7!pDvnS-xtn~GuZi~@;IHPwAi&i*w-z%m|$<=ki^z9}qPAE#2q@kc67@ zM3v*DaVuzyuYTaQEzDD3!YeUsYqhh}X>bj9OV9aH#Y)V3PqL+AArXgtOqDA)S{qB?pA$g*x# zj6j5kiFcmRvx?Qrtz+6Symdcq<-81OpIWyT8py#CgEd{Sz4Y0QXFoNc=vj;Va(Cp) zID9uaA_TP&-J3yy$FCI(^!SkS7m5Nzc=^}X+P_g3%QWRoTmHYOVU)^GjCnsen9CQQ z;_n@}eIvgxD;+(*(_q{SmFjrU&|%*Xk^80KR4)8gk@Gg`?h!)`VB18E*2yu#{F)4FZ}Ff079Ms*NG z6_&%0+lPzMV3s)yU>;59OHu4yA5GC{5E)jAU(CDjKLLsrqlm<5sYv#YFSoPSSbRLZ zUBP#q60K;|kZcesomWeP0Sbib!^!1S&1`?57Qd{}#XRtEr*%`R?MJROC|8Ox?!dZ# zw~IXcOa&Io#2>H)-arK)FH8b7{LBRydqL3wPgf2k%KGFFHVB(T1?uInm?QRe$5Cqd z;T@!9rgdK~CcP|su!W*vOdn_zAE5`m#I(muc6xr{5;&=~!pA0YM%48@hVxW4%8By^zw4==0_d5vnv&m=Yl%PS2$ULiy02fKP?>NPXk#U>M9WqV+j{?IOR z6G@VN2iX7N5TJPA6NF37PT;c4O+rh#Z4?EF(Lgu%*`Z2H+Cu9%tBS$M2d1yd8Qwcp zqCNN%fCf*IHV?jLWLBmu^n6Rm{ld~-MN3U_!=^XH;N_Jr65+o1Z+dt2-@EUwN1YU? zYEG+`8{S)I(EY%IZKl?Vb`^!{z>+B%OZk{bstOJ48Q3B>5J4_QPv!?%X?o_f@+pz6 zWAvo?t*Fy?ub>bvmlB3|ovuqqc6g9CJaQpj8@T=o2To1X=6~Q5;u~t8qR>-%yk9d0 zt2X1kx!t;-j8xYqvCa8ThgXPAog_O?QQYwTx*~7Ah|kAdHSR5$XB9BRo3m}ARKj-* za+i+XN=Pqf8biiVe_?F%JcoD%r$u`z+XQh2Nnv9F9+vU1QTlSV0YmTZRr894nG<;V zkYAn~etY2WKz36;A<)@-3fRv9r#ozxG2AHgW#qvjw~I!sMVOS02OC|#y3b^ zE4pA_w|Tj#SU)Aqy*5Anh4{(o;0K4!QNDZ?RajV~8q=R%TZHP*-qz0y7$EZ@iS(~t z{0oerd-2yZ-dBO~Yd_#&41_N!&Cgv};x5RhuevU;B*k`i-{uiEnnGlpRwqI~JUeH% zuyIlp$(7fJ7N-8f(9e5SE=%x1d9a$P{}3zER5@*6(-B>9S$=Ac)4*t|dPWWoO5WZ> zLb9iT{Bb5&Kb&~ZBc@_jg@%h-`a6HBtN}BXK|#+_PAo{eLmP*H0Sktj29;Hhf=d&1 z6ICbqeN!0AX$(ZryxhW>{L<(wm}$Aig7)`gX6D?ABGpPu?eO*<0CF~YWACqt|ACxz zC0j9>xRSfY8x|BW*&eN8)VPW9>w%5pW`&8RD(mX)!c~E z-9^NuA5(_zf8nyS#JR-_4M)KC^uyXs{AMP9GsQt!5=PI}l-;EN37?DvD!eOn{(e@S z2j*1E1eFO~pt3cMY*6|F6|RR5ss;csl&;#7u+l#GDXY zhb}p@Ixz`y#H4~#YUn4kYxQ7yekOQ>3lE{^rvCYb70C{HL&|FyD|8u#*c$H5Zk z6BI|II$v;Y);H4sLx?3d?;`Fg{67JdVq1mgd9O8CpCJYeCD|GYr5pP6MIm@`4mxYw zet==I0{>jR%s@S2mb>k8=fOPZ)>_ zfse!r1@ZX)ksVKhqC88<^jZn{8@}sI6f1QZx)vNx9m zZ`~B@an@evU|pB%e=ERVN%lg$4u6INIiXODv1E3cwlOp2DMmIqllcWs-X6AhGA4j! z3Vt^P7Hnj~na)J-!!RWUlaqO3ES^}n>xrvtJZfPks_?)U)9fvs1I3Yfo1x_V>hn@^ z+vP*WgSZUpwfKUWZ*s?ua|k7i5wSmTJ)(JlW1^pCU;zVeWP~7v-o_B$$HAk<8ovt6 z`jX*pfxyJPA}dn`+W8*NYzD*GlDvr@uf<5GFgPS9f(YsMI+kav6uTFNxud%SKD=;^ zmpvBFSvjWiWx~RwQv$*`Ooa>VFNQ%F&eJt-C4157Nk2V{qC2dOz7Tzuc}o)f#*wsn z2kJrB0!0y&aN6Ab=URa9H4BBEXt46 z&w6JC_ah+sfIo5>)>C^$C<`(DN0HuL*}5-*UKi$?ZevJ1%WY47(B&B%P}=LBebQ`| z@NUcoQ{^nlz0l1sHw|>Vu*9S!e}7(P`SkB=zh5(At;?q`jy45@Mu$Hkct^oVA8vPA+Khs*p}>9sLZ5SR z3!;N9D?1fpI?Uydh;G41qH(A@1r-cw7SMmSNa;BdJJ}c?$3g#IlseZegGFBJYOu1&zxeUO zbo{&?QEu6Oxv+<%TGWXUf>M*&!e%mPO8)|elJI%gqQPdT$XrZTtRL${$r@><#RW6` zL1CQM3{t6{rwA%#x1Txl7)YU)%z=)YlZ_7Sf;R)xQC}<){N5B!N^IbmgLMklo#*L{-Hx!z$`@6s~?c zM47g{Y4=jqGou6+K{jAi$q5+J8tdkv0*1}7{Tc*``TvGc)L}F3?3aL?BG9#B3-}uG zz4($9%;@-c=<&aeBL92npX2F&!Ij8EcFBfZ-uR&fuVkj{(N6j7#@WIbYf5jf$#rGO zv++nvfa9X+5-l-l4ReJQ$$KoYQeG31$p{N&D7e!av)4}prBf$6&(CK1gY?n&4Lhx7 z=1V*d%TVDUhUM?DeG&v+vWN4^m-#^;Li4eo7=p;E48vzVBk7bbWkBwBhwf4N}*!jLip3_LWfQnEdb)%SgenZ_Ji!7M`7NEj^Y_qk^m>zDRq1aAltN4l8@7(lCEDehnWJwzLOC;a;VNt49ELFi+tv;?26fxs_>pYY?gV%4fJq|1O|N<0D* zacD(WtuvuMWjt~5cDnGi1*Yvy>Pf7Y6|j^ZhDjEP3_*t5yByE<>6vZFWdbB|8v=Q1 zH1U54U`RM&X$P#~lngr}y(sRxyv+?8l|4iqHpYbJZHJm-mJIoD`UcGhs_&hzVa(Cr zNUioANB>}%H+5NAZh0h{&ApU68o+r)ii2jlZvKdTmqN4Y8jY7!;<9 z(dQ?JIk-lQL#7po`!%c5g+n%ioBm;CX)IckbieI;ZgI;E(N~sjdX15Y^#Or-#XX*{ ztRNVgH2VHH_2pm+Cu78^OTo~FG#RltHDK@VSuH0OTM{3TA9~Y7Hw`$hAbMuA6*sKz zyUPwBTW_0>f`j0#SKsSD49^f)6TFap&Q!RIadX6I?Ic_2E*ucF@-I2eHk0mkvC~^O z`X;r=L1nfGkzoTge{)_OzS!H*a2Gm#B0Iv1RKmb}xg~kCv2bEVa_2(#D1|ZL8%e_) zmZx%3+1^?KzNbmU!y5W1Zgjuc;Hs+s6Z{Tq(#pwTY?b|@Z%Z;L_qCapFclrP7YO}M znQrtLWy;1^IDp?BXP~?A`pRW2+?neM@DZ&tIn3wB-$pj&P3NFC{syZ060vD@l8mkt!I{GR zkzEP-)zKu>r=t?$*#hG;8!D}ltvl$=Z24n%RhGV!kLjkp%Q<+qq3d`b!9xICZQjc3xFu2fGD@iCUCwo?9WF1;x zdK19)qA1P#RjJ`6v^^I*bzc-L2l}5GV#BI66L(97V_kMWhF6k`DCtugW495EBnK;6 z1$y6<81H;eY`4|T+~wJD6ROu6?S7&bcm4x;Rz7(dKv6zJAt)<{uqm+JCI~ol==?RtFYh6=lUh0?uzEvU*_KHqa1>GA~$Vq0{@>l;8 z7WVEH+ah{*9Gq1yj1RUEzBh4s3Ekx(TI@|Rf>XZSZ^}LU2DxaCM?`v3$ZkBeQb>Iz z0ar_3Uq3EP1BmrCr0_X?CS^+2jh1@q-S^wG>e3}VclDV67Kc3U88I2Hv|cMTd5j~d zBfJhX%2SbvjC0sX5(zpZtd82KKg|E+330ZfxCi#Gj%;-tFNbP9T^~&PmPA~oZCbF} zU!BX}E9J3fD=$9TUDNgKwQjVy9DTTTC({Xu-Ao9)S?wE#r#TYe6DRcxun7q% zbh-l-^jjc~?~FVUE^pYF)iHm@d!wZXjn#t}VTI*bX(ebUNe>Ze@_f#V z$XNXxpK(bgYh#U4F>Dp86E%Y)(}+rYAcm8U=H*B&D4a~nSh6rMPsBg6zFXM3&4$}S z$N+rN>z%L01bpTa)6>z?m6gdW$F-|VN4WLo4S}WBXlP}mB&iRcsD1n_?dm902#c+$ zsAH|CJ?k|&|2ah2XHaM}o+nZsxOiUaAoy8YE)ci-?AnnTB4X_o8YV$rA;A_! zsf;EWi6=#vvcg=e$viMyuIgb+9JawIXScqv3Sf|4e@C`E8LqUA0uILrC-1{x42Qpr zd`S^_O#Wu107v|A=BTjaJl$uG!tJdH^+s0V`7IR<4^I}$abd^vt;d-c;@I)kMqO~R z7lMyZ;bMEyEcSby2Jg73S8QuM_8GsU?&bzDR+|bQzL6BAd(91ER@}KAt@-#anlav1 z>Skp=|N0RWXq2jz-Q&vT+86wM11hu!mtOq7u^976E13hPe@{B^v~m$nIOaRA95Mv5 zBnrB?xPv{U6z*4c0(wj*oQ&4?3Ebq8I_m}u#SZH2y__mmtv|Ks-W6Z-(;zSG=AUQ1 zUuspp7LlfQ1wNfH+@~6ETh*`4*+GnLhv}9je~GUQHvlY(0IMJEs2m`&*{Tz(e50nAnM!;R-*Dmok7*M4>WbY!4{?Uz#khzp zJ^kkU&tB3NKP(ZvU7+52dThRp-!VcawvU}METmEe)16C)m?yA&7&0oC52b!(zG3=J z7mY9^BK<(tb7{8)9J?Hh$q_oeA+l6t^}O~Nb6*PGc(mHQo$gDZ}N%@QvLlfYC`ISt7SxDQfav0j+b2}7v<^w&;EVgISF&a$$CPN<=O~y-=3rrQ%Rq=i#76={ub8_7>^$*V>x8U5fJm^ zMr6tvRlS(6zkTfXfUV<&G)7uS4Jdx=sd>e3OU}NYk%-D8(&uD)MVO5J{T!Z&v zyL}lyfMn8PhLU2`t@b&hveWskN97Ii6F^x%=UQStV!I*jdCTq!IU<=Q({)KbXAzCB zszu-#c;~wwkyK<0wJVn}zqEI~if*0-27D!bPJmM8H~W*j#*NYV>*zV;+{P|)Kwn|! zZvi}>Pjcvds=(0+JdKVYnZ;>0uYS1l%yY??g0j*!p~-98GOuin5_PAGO?3Li85L)VW-2$VQ0h7i;oAlAn{= z`xS!hU{3B+FEsN2(RFMiEUzmAuZQri<&lcpG2%l%6(`n2W!)iX(o);g?~5|_@n zti56b8lHiPTPA+$8r;>mwnmXHd@>aAdh;Utx=Ei?%PH%}*WIp_*DLIM#fwJkG8uxg zGfq-x>qw6RJENmyZ|qFYquD&V1m?XDkv&L_o~0aoG_KG|*sn?os=yynEmEF0U%?cU zG?$9|n|*a&>IR9z(CvwpZaL-6=tVj-q{zjWx;ft~H!rKs&6U2>>~xtu>`YLNa&#d% z=n-h1Z^)J@5F<}g5c4|TR6gzJ5a2I(UeYQuzkSQFbuuhreIQQc~BvmEXuIdXJ1yN~npXUw@S2grCS-X(;R{AY3p@^@dm|6wH ze~b~+PU+ViI)0kSZ^m!RSx}x#R3#OqG)Hgqed+~ zId8f9T8?cd3w0&ZakJpXMDn#)TY6%Oa4EU4JGX9kr{`R3^Q~85q3^`pg4dMZhH|y2 zy6elPM|0=Hxv(fkB-GvBk0IN&x3lSJ{(ug^I&2i^@V+ZQZE|n1EcBhLZ)rGdx45Wr zY9iGzY&AQ)*hV7w6%vDIMBrn|;(st{_`SS_yGFaY;sz3b5FW4=DSXJ%`M7Q62%@1| zWcIRINRVlD8Df&}zakj-b-t+b6HugMvK^Bb#`qTS){WO^Ii_Wt(7fkLH|SHhft{9r zt69z5;)YcDIIy7Qb*d!M!s1IXli-cZT}>M__B(v;VgAiEt~%Z5ju13S&1MVIxdkWK zAwrryZz3*0tya9wA#X*TOfs}5Vph2V*mO=8R3&Yb8xEG$XxZHugUn>)YP$O zZoIZDS&_OlpEa43FiYUhQZ}6PJYE{4deimY`SV?d5x&Ff{11l&3ANcGfpkG1Yxm+V zf;r%Ze46hLxVT2X>IX-L{GG-JJxWU*hqa5Cf_$QL0_q%ZFw^bhc{9naOGg86KIc_} zu}lj!Se%tu?%70SzT14xPhch=1|FCAZFxER3%c7Yk=Rsss>j2hlQ;|Ch@MP8Txhph z1(72?wJvEJQI5DaS_wb`Zms46YF8|Ge_osts}E z-_~RdnAiVL%P`8n;%vT%WBs*V(wq0UF8HU)-_=6@^2YxInxl()&vA>s`qAP_Pbq`C zFzpLPGdyAtS1-tfReh$Gk|SkMSqV$Amkp-Q8HIS3mB_iSa&rZKm|y_+lrqQ!4j;K| zro0ZC4|lSK3aNz_OWhXt6(eRKj+As)@%x=P;TB5ys^{z#WiuYF%_H_fN>D?}uwuYG z<)s9LQUgaK!xO)fXJ~U6K{pSgqL&N-`ZdIXA1ro^HUs0yX=Yo;f<-`Z6DFdU>7Nl$ zlK~H(zLMWXvyQIDRdr)JB%&rw+M2^tv%9#7>Aljx;V%`5o0-Q1-+LwcgE#qyvx>~LSDi`Y_9$hsx5d#s zH*AqqE71fkIiCmZ^U^qvtj!@Pwrf}hCj`_LmHFlGV$zz?5)ZAbE}-d>s`-|UU(e#GBe}zL zN?r*Du@5wvSCHGd(eFSf4z0d5Ugkmj9Yrsbk)m6=`F6jlsxfzrBFYvB3)>Qxr$Qvj z-9lA(b*CsbMzEVM-S^(74Tl1l`{-k-QKbzqD>bb$*{r#_8sgOwwO`wXz72{c?O*nm z*xX>1!PpfR*0caveSE%DS}|gfd0BD8yz0ETT9SG`^PVSzShN2f6BuGojic1U{hmlE*Xr}*F{`(* zyf4l7j(Y>99s#gNTjEj7zSMr}Ttn=OLo`w8v-B9r$! zyvSBEZ)L3p5;000!Zo?oL$5DQX(s>Pr4B%ZZ<7V#=u zhLV46#9mUVndwN&of{YVpu3Sff7=rQ0X-!EZbyMHf|MdN274TxAI}L0AjWB98+77? zZa#oi?g<$)dJCHmus-gC@~J#q)^?74X+%g|pma>f!fX}XkOnw`=(@*sE;cgK`r zjZ4_3z&9jjdX+J;Z7r`|R9>(}3S9m6G>2Q}XCQV6iD1d7e!j4^nEovcJ55q$sl3j+4d^!f}$CS%2Q7LIFEn z>~sU`($ecCacC));rF(q45>0(jqda4INxJdAwXS+EZCpW1rX~6hr#+%~H0o-&7NYmRNC(tq2EKyKBw)PU$&Dywnfwi@Sm0eS2$(KF9W3 zIOj>V8Oq~Y-3iw5L1RoJwCqwoe0C3~vNIR}2xJ5u?D8UsxR zb^_;CN45KQX$D&dlwb!;xZZ@5H46-4F~}BqI9_~l{UJ5R z%l5iC|K`OP1VGE`(kbJc4%l&VUh}2zXri!2VW7~a8h&?KU6P_v3joX>5mxqy^jHiR zk8xt5;dT;GyudM9&UgX)!ttr?0jCA9%|}=koOm13pU0mv|FwhYyb+9Ocz*s}vZV=o f_m_YE*C4>zbanOGN%ueM` literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-batchnorm/index.html b/apps/website/public/widgets/nn-batchnorm/index.html new file mode 100644 index 0000000000..6a4920cd43 --- /dev/null +++ b/apps/website/public/widgets/nn-batchnorm/index.html @@ -0,0 +1,47 @@ + + + + + + +Batch norm: features on very different scales, made comparable · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Batch norm: features on very different scales, made comparable

+

A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/batchnorm_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 12 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-batchnorm/logic.js b/apps/website/public/widgets/nn-batchnorm/logic.js new file mode 100644 index 0000000000..30a29340cc --- /dev/null +++ b/apps/website/public/widgets/nn-batchnorm/logic.js @@ -0,0 +1,36 @@ +// Generated by scripts/t27-logic.mjs from batchnorm_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 479b0fe4e0c7103ae57150096356ef13b6bdc796f6189d8cb563e4d26c115254 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-batchnorm/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABEgNgAAF/YAJ/fwF9YAN9f38BfQMFBAABAQIEBQFwAQEBBQMBABEGCQF/AUGAgMAACwdOBQZtZW1vcnkCAA90MjdfdmFsaWRfaW5wdXQAAAx0MjdfdHJhaW5fYXQAAQ90MjdfYmFja3dhcmRfYXQAAg50MjdfZm9yd2FyZF9hdAADCowGBAQAQQMLtQIEBH8BfQF/An0jgICAgABBMGsiAiSAgICAAEEAIQMCQEEwRQ0AIAJBAEEw/AsAC0GAgMCAACEEIAIhBQJAA0AgA0EDRg0BQwAAAAAhBkEAIQcCQANAIAdBMEYNASAGIAQgB2oqAgCSIQYgB0EMaiEHDAALCyAGQwAAgD6UIQhDAAAAACEGQQAhBwJAA0AgB0EwRg0BIAYgBCAHaioCACAIkyIJIAmUkiEGIAdBDGohBwwACwsgBkMAAIA+lEOsxSc3kpEhBkEAIQcCQANAIAdBMEYNASAFIAdqIAQgB2oqAgAgCJMgBpVDAAAAAJI4AgAgB0EMaiEHDAALCyAFQQRqIQUgBEEEaiEEIANBAWohAwwACwsgAiAAQQxsaiABQQJ0aioCACEGIAJBMGokgICAgAAgBgumAQICfwF9I4CAgIAAQTBrIgIkgICAgAAgAkGs////AzYCJCACQqz////D9f//PzcCKCACQYCAgPwDNgIYIAJCgICA/IOAgMA/NwIcIAJCrP//+8P1//8/NwIMIAJBwf//gQQ2AhQgAkEMaiEDAkACQAJAIAAOAgIAAQsgAkEYaiEDDAELIAJBJGohAwsgAyABQQJ0aioCACEEIAJBMGokgICAgAAgBAulAgECfyOAgICAAEHAAGsiAySAgICAACADQYCAgPwDNgIsIANCgICA/IOAgMA/NwIkQQAhBCADQQA2AiAgA0IANwIYIAMgADgCFCADIAA4AhAgAyAAOAIMAkAgAUEBcUUNACADQYCAgIAENgIgIANCgICAgISAgIDAADcCGCADQYCAgIQENgIsIANCgICAhISAgMDAADcCJAsgA0E4akEANgIAIANCADcDMAJAA0AgBEEMRg0BIANBMGogBGogA0EMaiAEaioCACAEQbCAwIAAaioCACADQRhqIARqKgIAkyADQSRqIARqKgIAQ6zFJzeSkZWUQwAAgD6SOAIAIARBBGohBAwACwsgA0EwaiACQQJ0aioCACEAIANBwABqJICAgIAAIAALC0UBAEGAgMAACzwAAIA/AAAgQQAAgL8AAABAAACgQQAAgL8AAEBAAADwQQAAgD8AAIBAAAAgQgAAgD8AAIA/AAAAQAAAQEA="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forwardAt(g, shifted, index) { + return W.t27_forward_at(g, shifted ? 1 : 0, int(index, 0, 4294967295, "forward_at.index")); +} +function backwardAt(which, index) { + return W.t27_backward_at(int(which, 0, 255, "backward_at.which"), int(index, 0, 4294967295, "backward_at.index")); +} +function trainAt(b, f) { + return W.t27_train_at(int(b, 0, 4294967295, "train_at.b"), int(f, 0, 4294967295, "train_at.f")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "forward_train", "cfg"]); +export { + __NOT_LOWERED__, + backwardAt, + forwardAt, + trainAt, + validInput +}; diff --git a/apps/website/public/widgets/nn-batchnorm/logic.t27 b/apps/website/public/widgets/nn-batchnorm/logic.t27 new file mode 100644 index 0000000000..e910bfe464 --- /dev/null +++ b/apps/website/public/widgets/nn-batchnorm/logic.t27 @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Prevent division by zero in sqrt | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward copied one element and backward zeroed two gradients +// (placeholders), and the tests pinned those placeholders: output[0] == input[0], +// grad_gamma[0] == grad_beta[0] == 0. They now compute batch normalisation: +// forward/backward in inference form, normalising by the running statistics, and +// forward_train normalising by the batch's own mean and variance. + +module Batchnorm; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_EPSILON : f32 = 1.0e-5; + const DEFAULT_MOMENTUM : f32 = 0.1; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const BatchNormConfig = struct { + num_features : u32, + epsilon : f32, + momentum : f32, + affine : bool, + track_running_stats : bool, + }; + + pub const BatchNormState = struct { + running_mean : []f32, + running_var : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // Inference: output[f] = gamma[f] (input[f] - running_mean[f]) / sqrt(running_var[f] + eps) + beta[f] + fn forward(input: []const f32, gamma: []const f32, beta: []const f32, state: BatchNormState, output: []f32, config: BatchNormConfig) -> void { + var f : usize = 0; + while (f < config.num_features) { + const x_hat = (input[f] - state.running_mean[f]) / sqrt(state.running_var[f] + config.epsilon); + output[f] = gamma[f] * x_hat + beta[f]; + f = f + 1; + } + } + + // Inference backward (mean and variance are constants here): + // grad_input[f] = grad_output[f] gamma[f] / sqrt(var[f] + eps) + // grad_gamma[f] = grad_output[f] x_hat[f], grad_beta[f] = grad_output[f] + fn backward(grad_output: []const f32, input: []const f32, gamma: []const f32, beta: []const f32, mean: []const f32, var: []const f32, grad_gamma: []f32, grad_beta: []f32, grad_input: []f32, config: BatchNormConfig) -> void { + var f : usize = 0; + while (f < config.num_features) { + const inv_std = 1.0 / sqrt(var[f] + config.epsilon); + grad_gamma[f] = grad_output[f] * (input[f] - mean[f]) * inv_std; + grad_beta[f] = grad_output[f]; + grad_input[f] = grad_output[f] * gamma[f] * inv_std; + f = f + 1; + } + } + + // Training: input is batch x num_features, row-major. Each feature is normalised by + // its own batch mean and (biased) batch variance, then scaled and shifted. + fn forward_train(input: []const f32, batch: usize, gamma: []const f32, beta: []const f32, output: []f32, config: BatchNormConfig) -> void { + const nf : usize = config.num_features; + var f : usize = 0; + while (f < nf) { + var mean : f32 = 0.0; + var b : usize = 0; + while (b < batch) { + mean = mean + input[b * nf + f]; + b = b + 1; + } + mean = mean / @as(f32, @floatFromInt(batch)); + var variance : f32 = 0.0; + b = 0; + while (b < batch) { + const d = input[b * nf + f] - mean; + variance = variance + d * d; + b = b + 1; + } + variance = variance / @as(f32, @floatFromInt(batch)); + b = 0; + while (b < batch) { + output[b * nf + f] = gamma[f] * (input[b * nf + f] - mean) / sqrt(variance + config.epsilon) + beta[f]; + b = b + 1; + } + f = f + 1; + } + } + + fn cfg() -> BatchNormConfig { + return BatchNormConfig{ .num_features = 3, .epsilon = DEFAULT_EPSILON, .momentum = DEFAULT_MOMENTUM, .affine = true, .track_running_stats = true }; + } + + // forward on input (1, 2, 3), gamma g, beta 0.25, running mean 0 / var 1 (or mean 2 / var 4) + fn forward_at(g: f32, shifted: bool, index: usize) -> f32 { + const input : [3]f32 = [1.0, 2.0, 3.0]; + const gamma : [3]f32 = [g, g, g]; + const beta : [3]f32 = [0.25, 0.25, 0.25]; + var mean : [3]f32 = [0.0, 0.0, 0.0]; + var variance : [3]f32 = [1.0, 1.0, 1.0]; + if (shifted) { + mean = [2.0, 2.0, 2.0]; + variance = [4.0, 4.0, 4.0]; + } + const state = BatchNormState{ .running_mean = &mean, .running_var = &variance }; + var output : [3]f32 = [0.0] ** 3; + forward(&input, &gamma, &beta, state, &output, cfg()); + return output[index]; + } + + // which: 0 = grad_gamma, 1 = grad_beta, 2 = grad_input; grad_output 1, gamma 2, mean 0, var 1 + fn backward_at(which: u8, index: usize) -> f32 { + const grad_output : [3]f32 = [1.0, 1.0, 1.0]; + const input : [3]f32 = [1.0, 2.0, 3.0]; + const gamma : [3]f32 = [2.0, 2.0, 2.0]; + const beta : [3]f32 = [0.0, 0.0, 0.0]; + const mean : [3]f32 = [0.0, 0.0, 0.0]; + const variance : [3]f32 = [1.0, 1.0, 1.0]; + var grad_gamma : [3]f32 = [9.0] ** 3; + var grad_beta : [3]f32 = [9.0] ** 3; + var grad_input : [3]f32 = [9.0] ** 3; + backward(&grad_output, &input, &gamma, &beta, &mean, &variance, &grad_gamma, &grad_beta, &grad_input, cfg()); + if (which == 0) { + return grad_gamma[index]; + } + if (which == 1) { + return grad_beta[index]; + } + return grad_input[index]; + } + + // forward_train on a batch of 4 samples x 3 features; returns output[b][f] + fn train_at(b: usize, f: usize) -> f32 { + const input : [12]f32 = [1.0, 10.0, -1.0, 2.0, 20.0, -1.0, 3.0, 30.0, 1.0, 4.0, 40.0, 1.0]; + const gamma : [3]f32 = [1.0, 1.0, 1.0]; + const beta : [3]f32 = [0.0, 0.0, 0.0]; + var output : [12]f32 = [0.0] ** 12; + forward_train(&input, 4, &gamma, &beta, &output, cfg()); + return output[b * 3 + f]; + } + + fn valid_input() -> u32 { + return cfg().num_features; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // With mean 0, var 1, gamma 1, beta 0 the layer is the identity up to eps: + // 1 / sqrt(1 + 1e-5) = 0.999995 (the old `==` held only for the copy placeholder) + test "forward_basic_case" + given out0 = forward_at(1.0, false, 0) - 0.25 + when out2 = forward_at(1.0, false, 2) - 0.25 + then @abs(out0 - 1.0) < 0.00001 and @abs(out2 - 3.0) < 0.00003 + + // mean 2, var 4: (x - 2) / 2 * gamma + beta, so x = 3 with gamma 2 gives 1.25 + test "forward_uses_running_statistics" + given result = forward_at(2.0, true, 2) + when centre = forward_at(2.0, true, 1) + then @abs(result - 1.25) < 0.00001 and centre == 0.25 + + // grad_gamma = g x_hat = (1, 2, 3) / sqrt(1 + eps), grad_beta = g = 1, + // grad_input = g gamma / sqrt(1 + eps) = 2 (the old 0, 0 were the placeholder's) + test "backward_basic_case" + given grad_gamma = backward_at(0, 2) + when grad_input = backward_at(2, 0) + then @abs(grad_gamma - 3.0) < 0.0001 and backward_at(1, 0) == 1.0 and grad_input != 0.0 and @abs(grad_input - 2.0) < 0.0001 + + // Each feature of the batch comes out with mean 0 and variance 1 + test "forward_train_normalises_each_feature" + given mean_f1 = train_at(0, 1) + train_at(1, 1) + train_at(2, 1) + train_at(3, 1) + when var_f1 = (train_at(0, 1) * train_at(0, 1) + train_at(1, 1) * train_at(1, 1) + train_at(2, 1) * train_at(2, 1) + train_at(3, 1) * train_at(3, 1)) / 4.0 + then @abs(mean_f1) < 0.00001 and @abs(var_f1 - 1.0) < 0.0001 and @abs(train_at(0, 0) - train_at(0, 1)) < 0.00001 and @abs(train_at(0, 2) + 1.0) < 0.0001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // num_features > 0 + invariant batchnorm_constraint_0 + assert valid_input() > 0 + + // epsilon > 0 + invariant batchnorm_constraint_1 + assert DEFAULT_EPSILON > 0.0 + + // 0 <= momentum < 1 + invariant batchnorm_constraint_2 + assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0 + + // gamma.size() == num_features: the fixtures carry 3 of each + invariant batchnorm_constraint_3 + assert valid_input() == 3 + + // beta.size() == num_features: beta shifts every feature, so x = mean gives exactly beta + invariant batchnorm_constraint_4 + assert forward_at(2.0, true, 1) == 0.25 diff --git a/apps/website/public/widgets/nn-batchnorm/nn-batchnorm.t27 b/apps/website/public/widgets/nn-batchnorm/nn-batchnorm.t27 new file mode 100644 index 0000000000..5c886e03c8 --- /dev/null +++ b/apps/website/public/widgets/nn-batchnorm/nn-batchnorm.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-batchnorm.t27 -- batch normalisation: features on different scales, made comparable +; Source of truth for public/widgets/nn-batchnorm/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-batchnorm/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/batchnorm_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 12 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader reads the batch before and after and sets gamma and the running +; statistics. The normalised batch is train_at(b, f) and the inference bars forward_at(gamma, +; shifted, i) on inputs (1, 2, 3), beta 0.25. + +; WHAT IT DOES NOT CLAIM: the batch on the left is the spec's fixture, repeated as K_BATCH; the +; normalised values come from the compiled fn. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_batchnorm; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-batchnorm"; +pub const TITLE : str = "Batch norm: features on very different scales, made comparable"; +pub const DESCRIPTION : str = "A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference."; +pub const IMAGE_ALT : str = "Batch-norm card: on the left the spec's batch, 4 samples by 3 features (1, 2, 3, 4 / 10, 20, 30, 40 / -1, -1, 1, 1); on the right the normalised batch, the first two columns both -1.34, -0.45, 0.45, 1.34 and the third -1.00, -1.00, 1.00, 1.00. Below, gamma 1 at inference gives 1.25, 2.25, 3.25."; +pub const HOOK : str = "Features 1..4 and 10..40 come out identical, -1.34, -0.45, 0.45, 1.34: batch norm keeps the shape of each feature and throws away its scale."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/batchnorm_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 12 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_BATCH_ROWS : u8 = 4; +pub const K_FEATURES : u8 = 3; +pub const K_BATCH : [12]i8 = [1, 10, -1, 2, 20, -1, 3, 30, 1, 4, 40, 1]; +pub const K_GAMMA_HI_C : u16 = 300; +pub const K_INFER_INPUT : [3]u8 = [1, 2, 3]; +pub const K_BAR_LO_C : i16 = -200; +pub const K_BAR_HI_C : u16 = 1000; +pub const K_BAR_TICKS : [5]i8 = [-2, 0, 2, 5, 10]; +pub const K_PRESET_GAMMA_C : [4]u16 = [100, 200, 100, 50]; +pub const K_PRESET_SHIFTED : [4]u8 = [0, 0, 1, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["gamma 1, mean 0 / var 1", "gamma 2", "gamma 1, mean 2 / var 4", "gamma 0.5, mean 2 / var 4"]; +pub const SAY_ASK : str = "What happens when one feature is ten times larger than another?"; +pub const SAY_GAMMA : str = "gamma"; +pub const SAY_SHIFTED : str = "running mean 2, variance 4"; +pub const SAY_BEFORE_LABEL : str = "The batch: 4 samples x 3 features"; +pub const SAY_AFTER_LABEL : str = "After batch norm"; +pub const SAY_INFER_LABEL : str = "At inference: inputs 1, 2, 3 through the running statistics"; +pub const SAY_FEATURE : str = "feature"; +pub const SAY_SAMPLE : str = "sample"; +pub const SAY_INPUT : str = "input"; +pub const SAY_COL : str = "feature {0} after"; +pub const SAY_INFER : str = "inference out"; +pub const SAY_NOTE : str = "Training normalises with the batch's own mean and variance; inference cannot, so it uses running averages kept during training. gamma and beta are learned, so the layer can undo the normalisation where that helps."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/batchnorm_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_batch_is_the_spec_fixture { + assert K_BATCH_ROWS * K_FEATURES == 12; + assert K_BATCH[1] == 10; + assert K_BATCH[10] == 40; + assert K_BATCH[2] + 1 == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_GAMMA_C[1] <= K_GAMMA_HI_C; + assert K_PRESET_SHIFTED[2] == 1; + assert K_INFER_INPUT[2] == 3; +} diff --git a/apps/website/public/widgets/nn-batchnorm/tool.js b/apps/website/public/widgets/nn-batchnorm/tool.js new file mode 100644 index 0000000000..db17b14c82 --- /dev/null +++ b/apps/website/public/widgets/nn-batchnorm/tool.js @@ -0,0 +1,40 @@ +// nn-batchnorm/tool.js -- lesson 12 of neural-networks: how a network copes with features on very +// different scales. Batch normalisation subtracts each feature's batch mean and divides by its batch +// spread, then scales by gamma and shifts by beta. Every normalised value is train_at, every +// inference value forward_at of gHashTag/t27 specs/ml/layers/batchnorm_layer.t27, compiled to wasm +// (./logic.js). The batch on the left is the spec's own (K_BATCH, held equal to it by the widget's +// tests). Words are SAY_ and numbers K_ constants of specs/widgets/nn-batchnorm.t27. +import { forwardAt, trainAt } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, el, fill, fmt, heat, root, say, source, tiles, tone } from '../nn-kit.js' + +const B = K('K_BATCH_ROWS', 4), F = K('K_FEATURES', 3) +const BATCH = K('K_BATCH', []) +const ctl = controls([ + { key: 'g', label: say('SAY_GAMMA'), min: 0, max: centi(K('K_GAMMA_HI_C', 300)), step: 0.05, fmt: (v) => fmt(v, 2) }, + { key: 'shifted', label: say('SAY_SHIFTED'), kind: 'toggle' }, +], { names: W.SAY_PRESET_NAMES, values: { g: K('K_PRESET_GAMMA_C', []).map(centi), shifted: K('K_PRESET_SHIFTED', []) } }, draw) + +const before = canvas('nn-heat', say('SAY_BEFORE_LABEL')) +const after = canvas('nn-heat', say('SAY_AFTER_LABEL')) +const inf = canvas('nn-bars', say('SAY_INFER_LABEL')) +const stat = el('div') +const cols = [...Array(F)].map((_, f) => `${say('SAY_FEATURE')} ${f}`) +const rows = [...Array(B)].map((_, b) => `${say('SAY_SAMPLE')} ${b}`) +root.replaceChildren(ask(say('SAY_ASK')), + el('div', { class: 'nn-two' }, el('div', {}, el('p', { class: 'dk-label' }, say('SAY_BEFORE_LABEL')), before), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_AFTER_LABEL')), after)), + stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), ctl.node, el('p', { class: 'dk-label' }, say('SAY_INFER_LABEL')), inf, source()) + +function draw(s) { + heat(before, { rows: B, cols: F, value: (r, c) => BATCH[r * F + c], color: (v) => tone(v, 40), rowLabels: rows, colLabels: cols, w: 400, cell: 96, fmt: (v) => fmt(v, 0) }) + heat(after, { rows: B, cols: F, value: (r, c) => trainAt(r, c), color: (v) => tone(v, 1.5), rowLabels: rows, colLabels: cols, w: 400, cell: 96, fmt: (v) => fmt(v, 2) }) + const y = [0, 1, 2].map((i) => forwardAt(s.g, !!s.shifted, i)) + bars(inf, { values: y, labels: K('K_INFER_INPUT', []).map((x) => `${say('SAY_INPUT')} ${x}`), colors: [COLORS[2], COLORS[0], COLORS[1]], lo: centi(K('K_BAR_LO_C', -200)), hi: centi(K('K_BAR_HI_C', 1000)), h: 240, ticks: K('K_BAR_TICKS', []), fmt: (v) => fmt(v, 3) }) + stat.replaceChildren(tiles([ + { label: fill(say('SAY_COL'), 0), value: [0, 1, 2, 3].map((b) => fmt(trainAt(b, 0), 2)).join(' '), tone: 0 }, + { label: fill(say('SAY_COL'), 1), value: [0, 1, 2, 3].map((b) => fmt(trainAt(b, 1), 2)).join(' '), tone: 1 }, + { label: fill(say('SAY_COL'), 2), value: [0, 1, 2, 3].map((b) => fmt(trainAt(b, 2), 2)).join(' '), tone: 2 }, + { label: say('SAY_INFER'), value: y.map((v) => fmt(v, 2)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-bce/card.png b/apps/website/public/widgets/nn-bce/card.png new file mode 100644 index 0000000000000000000000000000000000000000..5b1853131e75878c774d17bd2ddd3107577e3dd7 GIT binary patch literal 50312 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�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 z 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 + + + + + +Cross-entropy: why a confident wrong answer costs so much · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +

+Trinity S³AI +

Cross-entropy: why a confident wrong answer costs so much

+

Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 14 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-bce/logic.js b/apps/website/public/widgets/nn-bce/logic.js new file mode 100644 index 0000000000..c5bfba2dd1 --- /dev/null +++ b/apps/website/public/widgets/nn-bce/logic.js @@ -0,0 +1,44 @@ +// Generated by scripts/t27-logic.mjs from binary_crossentropy_loss.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 4b041a9197282c33abafdcc293c3864bae585c9e417d743e0081cf4d734fcf9b +// Imported by scripts/widget-logic.mjs for public/widgets/nn-bce/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function sigmoid(x) { + return W.t27_sigmoid(x); +} +function clip(p, eps) { + return W.t27_clip(p, eps); +} +function lossOf(a, b, c, fromLogits) { + return W.t27_loss_of(a, b, c, fromLogits ? 1 : 0); +} +function gradOf(a, b, c, fromLogits, index) { + return W.t27_grad_of(a, b, c, fromLogits ? 1 : 0, int(index, 0, 4294967295, "grad_of.index")); +} +function batchLoss() { + return W.t27_batch_loss(); +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["element_loss", "forward", "forward_batch", "gradient", "cfg"]); +export { + __NOT_LOWERED__, + batchLoss, + clip, + gradOf, + lossOf, + sigmoid, + validInput +}; diff --git a/apps/website/public/widgets/nn-bce/logic.t27 b/apps/website/public/widgets/nn-bce/logic.t27 new file mode 100644 index 0000000000..063ee794ce --- /dev/null +++ b/apps/website/public/widgets/nn-bce/logic.t27 @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Gradient w.r.t predictions | φ² + 1/φ² = 3 | TRINITY + +// #8980: never compiled (`new f32[n]`, a float loop index, `predictions.size`, +// an empty enum), and it approximated sigmoid and log with polynomials that +// were 0.3 off at x = 1. The probability gradient also had the wrong sign on its +// second term: d/dp of -(t log p + (1-t) log(1-p)) is -t/p + (1-t)/(1-p). It now +// uses exp and log, writes gradients into a caller's buffer, and reduces by mean. + +module BinaryCe; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_EPSILON : f32 = 1e-7; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const BinaryCEConfig = struct { + from_logits : bool, + epsilon : f32, + reduction : Reduction, + }; + + pub const Reduction = enum(u8) { + Mean, + Sum, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + fn sigmoid(x: f32) -> f32 { + if (x >= 0.0) { + return 1.0 / (1.0 + exp(-x)); + } + const e = exp(x); + return e / (1.0 + e); + } + + // p clipped into [eps, 1 - eps] so log stays finite + fn clip(p: f32, eps: f32) -> f32 { + if (p < eps) { + return eps; + } + if (p > 1.0 - eps) { + return 1.0 - eps; + } + return p; + } + + // -(t log p + (1 - t) log(1 - p)) for one element + fn element_loss(pred: f32, target: f32, config: BinaryCEConfig) -> f32 { + var p = pred; + if (config.from_logits) { + p = sigmoid(pred); + } + p = clip(p, config.epsilon); + return -(target * log(p) + (1.0 - target) * log(1.0 - p)); + } + + // mean (or sum) of element_loss + fn forward(predictions: []const f32, targets: []const f32, config: BinaryCEConfig) -> f32 { + var loss : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + loss = loss + element_loss(predictions[i], targets[i], config); + i = i + 1; + } + if (config.reduction == Reduction.Sum) { + return loss; + } + return loss / @as(f32, @floatFromInt(predictions.len)); + } + + // A batch of rows of width `width`, flattened row-major: the mean over every element + fn forward_batch(predictions: []const f32, width: usize, targets: []const f32, config: BinaryCEConfig) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + total = total + element_loss(predictions[i], targets[i], config); + i = i + 1; + } + _ = width; + return total / @as(f32, @floatFromInt(predictions.len)); + } + + // Per-element gradient of the (unreduced) loss: + // from logits: sigmoid(z) - t + // from probabilities: -t / p + (1 - t) / (1 - p) + fn gradient(predictions: []const f32, targets: []const f32, config: BinaryCEConfig, grads: []f32) -> void { + var i : usize = 0; + while (i < predictions.len) { + const t = targets[i]; + if (config.from_logits) { + grads[i] = sigmoid(predictions[i]) - t; + } else { + const p = clip(predictions[i], config.epsilon); + grads[i] = -t / p + (1.0 - t) / (1.0 - p); + } + i = i + 1; + } + } + + fn cfg(from_logits: bool) -> BinaryCEConfig { + return BinaryCEConfig{ .from_logits = from_logits, .epsilon = DEFAULT_EPSILON, .reduction = Reduction.Mean }; + } + + // The fixture: predictions (a, b, c) against targets (1, 0, 1) + fn loss_of(a: f32, b: f32, c: f32, from_logits: bool) -> f32 { + const predictions : [3]f32 = [a, b, c]; + const targets : [3]f32 = [1.0, 0.0, 1.0]; + return forward(&predictions, &targets, cfg(from_logits)); + } + + fn grad_of(a: f32, b: f32, c: f32, from_logits: bool, index: usize) -> f32 { + const predictions : [3]f32 = [a, b, c]; + const targets : [3]f32 = [1.0, 0.0, 1.0]; + var grads : [3]f32 = [9.0] ** 3; + gradient(&predictions, &targets, cfg(from_logits), &grads); + return grads[index]; + } + + fn batch_loss() -> f32 { + const predictions : [4]f32 = [0.8, 0.3, 0.9, 0.1]; + const targets : [4]f32 = [1.0, 0.0, 1.0, 0.0]; + return forward_batch(&predictions, 2, &targets, cfg(false)); + } + + fn valid_input() -> f32 { + return loss_of(0.8, 0.3, 0.9, false); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test sigmoid_basic_case + given input = 0.0 + when result = sigmoid(input) + then @abs(result - 0.5) < 1e-6 + + test sigmoid_positive_input + given input = 1.0 + when result = sigmoid(input) + then result > 0.5 and result < 1.0 and @abs(result - 0.7310586) < 0.000001 + + test sigmoid_negative_input + given input = -1.0 + when result = sigmoid(input) + then result > 0.0 and result < 0.5 and @abs(result + sigmoid(1.0) - 1.0) < 0.000001 + + // -(ln 0.8 + ln 0.7 + ln 0.9) / 3 = 0.2283930 + test forward_basic_case + given result = loss_of(0.8, 0.3, 0.9, false) + then result > 0.0 and @abs(result - 0.2283930) < 0.000001 + + // From logits (2, -1, 3) it is the same loss as from their sigmoids + test forward_from_logits_case + given result = loss_of(2.0, -1.0, 3.0, true) + when probs = loss_of(sigmoid(2.0), sigmoid(-1.0), sigmoid(3.0), false) + then result > 0.0 and @abs(result - probs) < 0.000001 + + // (-ln 0.8 - ln 0.7 - ln 0.9 - ln 0.9) / 4 = 0.1976349 + test forward_batch_basic_case + given result = batch_loss() + then result > 0.0 and @abs(result - 0.1976349) < 0.000001 + + // t = 1 pulls p up (negative gradient), t = 0 pushes it down (positive) + test gradient_basic_case + given g0 = grad_of(0.8, 0.3, 0.9, false, 0) + when g1 = grad_of(0.8, 0.3, 0.9, false, 1) + then g0 < 0.0 and g1 > 0.0 and grad_of(0.8, 0.3, 0.9, false, 2) < 0.0 and @abs(g0 + 1.25) < 0.000001 and @abs(g1 - 1.0 / 0.7) < 0.000001 + + // From logits: sigmoid(z) - t, and it matches a finite difference of the loss + test gradient_from_logits_case + given g1 = grad_of(2.0, -1.0, 3.0, true, 1) + when slope = 3.0 * (loss_of(2.0, -1.0 + 0.001, 3.0, true) - loss_of(2.0, -1.0 - 0.001, 3.0, true)) / 0.002 + then @abs(g1 - sigmoid(-1.0)) < 0.000001 and @abs(g1 - slope) < 0.001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // targets[i] in {0, 1}: a perfect prediction costs (almost) nothing + invariant binary_ce_constraint_0 + assert loss_of(1.0, 0.0, 1.0, false) < 0.000001 + + // 0 < epsilon << 1 + invariant binary_ce_constraint_1 + assert DEFAULT_EPSILON > 0.0 and DEFAULT_EPSILON < 0.001 + + // name: binary_ce -- positive for an imperfect prediction + invariant binary_ce_constraint_2 + assert valid_input() > 0.0 + + // name: gradient -- zero where the logit already gives the target + invariant binary_ce_constraint_3 + assert @abs(grad_of(30.0, -30.0, 30.0, true, 0)) < 0.000001 + + // "Bishop (2006) - Pattern Recognition and Machine Learning": the loss falls as p nears t + invariant binary_ce_constraint_4 + assert loss_of(0.9, 0.1, 0.9, false) < loss_of(0.6, 0.4, 0.6, false) + + // "Goodfellow et al. (2016) - Deep Learning": clipping keeps a certain wrong answer finite + invariant binary_ce_constraint_5 + assert loss_of(0.0, 1.0, 0.0, false) < 20.0 diff --git a/apps/website/public/widgets/nn-bce/nn-bce.t27 b/apps/website/public/widgets/nn-bce/nn-bce.t27 new file mode 100644 index 0000000000..c1f2b414ae --- /dev/null +++ b/apps/website/public/widgets/nn-bce/nn-bce.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-bce.t27 -- binary cross-entropy: why a confident wrong answer costs so much +; Source of truth for public/widgets/nn-bce/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-bce/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 14 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader moves three probabilities from 0.01 to 0.99. The loss is loss_of(a, b, c, +; false) against the spec's targets (1, 0, 1), the bars grad_of, and the curve loss_of over the +; first prediction; one tile feeds logits of 0 through the spec's sigmoid. + +; WHAT IT DOES NOT CLAIM: the spec clips each probability to [1e-7, 1 - 1e-7], so the curve is +; finite at the ends of this window. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_bce; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-bce"; +pub const TITLE : str = "Cross-entropy: why a confident wrong answer costs so much"; +pub const DESCRIPTION : str = "Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound."; +pub const IMAGE_ALT : str = "Cross-entropy card: predictions 0.8, 0.3 and 0.9 against targets 1, 0, 1. A red curve shows the loss as prediction 0 runs from 0.01 to 0.99, rising steeply on the left, with the cursor at 0.8; gradient bars read -1.25, 1.43 and -1.11. Tiles read loss 0.2284, sure and right 0.0101, sure and wrong 4.6052, logits at 0 giving 0.6931."; +pub const HOOK : str = "Predicting 0.99 where the answer is 1 costs 0.01; predicting 0.01 costs 4.6. The cost of a confident mistake is what trains a classifier."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 14 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_TARGETS : [3]u8 = [1, 0, 1]; +pub const K_P_LO_C : u8 = 1; +pub const K_P_HI_C : u8 = 99; +pub const K_X_TICKS_C : [5]u8 = [1, 25, 50, 75, 99]; +pub const K_LOSS_HI_C : u16 = 200; +pub const K_LOSS_TICKS_C : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_GRAD_LO_C : i16 = -1000; +pub const K_GRAD_HI_C : u16 = 1000; +pub const K_GRAD_TICKS : [5]i8 = [-10, -5, 0, 5, 10]; +pub const K_PRESET_A_C : [4]u8 = [80, 99, 10, 50]; +pub const K_PRESET_B_C : [4]u8 = [30, 1, 90, 50]; +pub const K_PRESET_C_C : [4]u8 = [90, 99, 10, 50]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["0.8, 0.3, 0.9", "Sure and right", "Sure and wrong", "Undecided"]; +pub const SAY_ASK : str = "Why does a confident wrong answer cost so much?"; +pub const SAY_PRED : str = "p"; +pub const SAY_TARGET : str = "answer"; +pub const SAY_CURVE_LABEL : str = "The loss as the first prediction moves, the others held"; +pub const SAY_GRAD_LABEL : str = "The gradient for each prediction"; +pub const SAY_LOSS : str = "loss"; +pub const SAY_SURE_RIGHT : str = "0.99 where right"; +pub const SAY_SURE_WRONG : str = "0.01 where right"; +pub const SAY_LOGITS : str = "logits 0, 0, 0"; +pub const SAY_NOTE : str = "The loss of one case is -(t log p + (1 - t) log(1 - p)). The gradient of a prediction is huge where the model is sure and wrong, and small where it is sure and right."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/binary_crossentropy_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_targets_are_the_spec_fixture { + assert K_TARGETS[0] == 1; + assert K_TARGETS[1] == 0; + assert K_TARGETS[2] == 1; +} + +test the_window_stays_inside_zero_and_one { + assert K_P_LO_C > 0; + assert K_P_HI_C < 100; + assert K_PRESET_B_C[1] == K_P_LO_C; + assert K_PRESET_A_C[1] == K_P_HI_C; +} diff --git a/apps/website/public/widgets/nn-bce/tool.js b/apps/website/public/widgets/nn-bce/tool.js new file mode 100644 index 0000000000..3cc561b509 --- /dev/null +++ b/apps/website/public/widgets/nn-bce/tool.js @@ -0,0 +1,37 @@ +// nn-bce/tool.js -- lesson 14 of neural-networks: why a confident wrong answer costs so much. Binary +// cross-entropy charges -log of the probability given to the true answer, so near 0 the cost climbs +// without bound (clipped at eps so it stays finite). Every value is loss_of or grad_of of +// gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27, compiled to wasm (./logic.js), against the +// spec's targets (1, 0, 1). Words are SAY_ and numbers K_ constants of specs/widgets/nn-bce.t27. +import { gradOf, lossOf } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const T = K('K_TARGETS', []) +const Q0 = centi(K('K_P_LO_C', 1)), Q1 = centi(K('K_P_HI_C', 99)) +const prob = (key, i) => ({ key, label: `${say('SAY_PRED')} ${i} (${say('SAY_TARGET')} ${T[i]})`, min: Q0, max: Q1, step: 0.01, fmt: (v) => fmt(v, 2) }) +const ctl = controls([prob('a', 0), prob('b', 1), prob('c', 2)], + { names: W.SAY_PRESET_NAMES, values: { a: K('K_PRESET_A_C', []).map(centi), b: K('K_PRESET_B_C', []).map(centi), c: K('K_PRESET_C_C', []).map(centi) } }, draw) + +const curve = canvas('nn-curve', say('SAY_CURVE_LABEL')) +const grads = canvas('nn-bars', say('SAY_GRAD_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, curve, legend([[say('SAY_LOSS'), COLORS[6]]]), el('p', { class: 'dk-label' }, say('SAY_GRAD_LABEL')), grads, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + curve.replaceChildren() + const o = { w: 640, h: 300, x0: Q0, x1: Q1, y0: 0, y1: centi(K('K_LOSS_HI_C', 200)), xticks: K('K_X_TICKS_C', []).map(centi), yticks: K('K_LOSS_TICKS_C', []).map(centi), xlabel: `${say('SAY_PRED')} 0 (${say('SAY_TARGET')} ${T[0]})` } + const p = plot(curve, o) + p.line(sample((x) => lossOf(x, s.b, s.c, false), Q0, Q1, 200), COLORS[6], 3) + cursor(curve, p, s.a, [[lossOf(s.a, s.b, s.c, false), COLORS[6]]]) + dragX(curve, p, o, (x) => ctl.set('a', x)) + const g = [0, 1, 2].map((i) => gradOf(s.a, s.b, s.c, false, i)) + bars(grads, { values: g, labels: [0, 1, 2].map((i) => `${say('SAY_PRED')} ${i}`), colors: g.map((v) => (v < 0 ? COLORS[0] : COLORS[3])), lo: centi(K('K_GRAD_LO_C', -1000)), hi: centi(K('K_GRAD_HI_C', 1000)), h: 220, ticks: K('K_GRAD_TICKS', []), fmt: (v) => fmt(v, 2) }) + stat.replaceChildren(tiles([ + { label: say('SAY_LOSS'), value: fmt(lossOf(s.a, s.b, s.c, false), 4), tone: 6 }, + { label: say('SAY_SURE_RIGHT'), value: fmt(lossOf(Q1, Q0, Q1, false), 4), tone: 0 }, + { label: say('SAY_SURE_WRONG'), value: fmt(lossOf(Q0, Q1, Q0, false), 4), tone: 'bad' }, + { label: say('SAY_LOGITS'), value: fmt(lossOf(0, 0, 0, true), 4), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-conv/card.png b/apps/website/public/widgets/nn-conv/card.png new file mode 100644 index 0000000000000000000000000000000000000000..cde11e50e315ec8a6f89d100c3356c1188cf48ff GIT binary patch literal 46014 zcmb@tWmuH$*XWIU3o0roB_JXt(%mWDoio5lH%K$oSctTAgLH%B5W|dubaxCPF?0?& zz`!27|If4E_u0pL9Q(uj>72Q)vumyOTk8td(olT#fa(Dr9^NBmB{>~DynlY+;obJW zcN_QQC;c`d9v(5CvfLXz-}LRd`vIiK*z1Emvl$<-63VG)PcaQ&ThP!z^}~Ip_n=CBrq3hlj}fPb&BFpPTrHL%zeUn+k-l8%$h6+MJ=yTU(}R2-4JS^knXq-@(Pj@9M(f@e03f*CvM= zm7A=11FEbED!JOqv7+2s9GXa{9jn&*+w=Q`?f!$|zwXF2DqmXF@BUUEd3lrhh|0UU zw0eYP@*xoTz5FT*(WImNsrrsQ>wjKzie~7rI$3@&*rOJc5%=_OJM!NWb|tX-HB zZJhzq0bDtrC$vSCE$L-D|EA~D&8wk{BE6FD-wixKrMVF{CR6;THuS_dDuKMV>&EK)DM>ajZ*Cvx%;Ox!%`EO}9d;Scfzdzr@Bc<=%JPQi@-{~2^ZZ)D2 z8ZowaVYe|-u2_D1oih6l1l+rQz@s?91v)u+W5AE=1XIgJ*x~TxrQ;sYR#iXb1tsgy z-ScdspnxvF?V)oZ{-)UZ*JdHwSmf;C-q1Ngi1)smr2n0k_mY150?@t`uimmyo?AJ4 zq43S%okwgxt1N@LKqN?C&Glp{SIIh;=SXBBeDp9*@_2K)X0z>I(N?7cp{{4Y@)OCkeR@#9Y5CIdNII?8r5AyS#<>z9PH#wP-s4?zIsI zOd^7zKqQ?VRd*)nw|5pGX`E6uI%XD(R@bYrlv_Cb9t^l2^_+h&ULd=5f zlcl5Cu9p%cf}r;xd77}xOtFd<{+~L=24pYdd^g4#RoTJKd*?-3czEwMM8!-Mj_*_& z9Sy9?uiC zB4^O`&*V{WvE$(sDC`HgIbaANX#)debtfN+9rK&tskHaIleU04B)g+2!RE55oa|nlq2vu~b@83o*%A&9W}>0ANg(TsO(`Ks zIa-OUs4u5Z3DF*icb#W;*y7mX#cO|d3F)ueMjM}?Cmp>m0Sujf+eas%aEpx- z%ZZ)v!q2RV{jSC^zf-eDJ^$^qljx**UbLQ%B<8-9!Q*_$W$VKHbinMP`Dx2Ld8b1k zN>TS+F%cDpfXlJ?bxwtrMELp_|5z@Bf4iS+E^6E5;9XG2g7nmoBY6u4H&xw-v7m6!e7Z;1=;P8gR*15S*tH|JIKkt13HarUAcR17*LTx3Jj-uC>@k@x zz}^<*xI@$fq@F$QiFk%l*p%3Vxb7&0v`qy4qv2&fg^juleca6zf9zhvCF=S8vNRTD z-(9k^H7O~OyI5fZ(b5;$y7oFnbgT680X{DirR~Luw~1LOGs2D1YCbgp|AkCqzS)1J~+`uq?byt?G(@aS*%Qo zNHE-guS$#5Di83X&DxZ%h^F!A)xkh_zoCP7&9LZCNkSLFV}%1j)*hWf_${t)u1Yb! zAX%Z~^nOj#MeKtzYY=CX2Vmwsp#>i=r`f)9{^c482~7tbD;{3c&&dzmZ(Hx|T`jEk zgAne$`?@tp*h*vcZW@ugS|s5QBlcTv8xO$@)gvFf2GmNr{eaPG zWgxIhUTlMvnsA%N*hUiFc$%H{`!zP|b~DS5`(ewGj|Tf-{5)!1TqKF2<|k~lh@zuk zqeSUd+gQUDA!0N5aw!dJv6y5Jd^pE6`8u2bB&_i2c&Uu-+;DHE)@29Um@q8M73pG| zWJoJ|R6?0VM4<==oG#A5HXF1jC6D@ADQTvEMNtaSl{p!@7)vir`M*dGEJllFFVp(2 zEeE6h$uHno?<9ePkrYCypygX&f?eN}lKkEUVA|G(zv0PF$!Q{@KA;@|=jxi%wt2$y ziA0tfq)8i>{G5aJ@bJOx9a{u?pxW4yAf)>dM=Ob9zu#&GnNL=t@@<9wbUvMJ0CYE; z24fH?EnSnCRdtrI_Nv3kn;nbVff#}26K=5rFgXdP<5Rt~*vaPTex>MxSrR_q&Drri zPIw78YWFwwP)MPfTklx5xi#2P%H&iZyuM#tlO(|>tD(Xn1PDUXzT&rD>Z7!@C_%$b znq5XEV?@m-bX5n0hlZ+?@9TyD(C7#3=AQ~B>yL(e6Fi+c7EXu5Cg(5qORH&N8&`(x z;On^sP#R}tQzEOQ@A+@a$=7Zzs(X#vOXD>K9WSPvyyu|JCGzQ#a%NdlL8n!vqn4~5 z2<&E&5~Y~q^roSWP(}LrZHwjU1p`W;Bvz@Fc6||OOocpv5g*L5wCVnzwOhS?t?(%9?S>VQaR~!eLjUAvDCZz z?k>s^G#iwKa*`)m&-jd@9x9?A0Q)~-J3)M}G`@}y?ZM7+!a3o4Z3TSOG9d%WA}aIQ zNcakcGKERJClVbf^V>A2H-7BfN+@4Jm;9GmCPQ_&LyvwO^L0>&JflVm507zWG>w2> zP<_vKKG8h*f~!zdc_8`n&qS^>L~?65+9rBXDb;&zS=EpORPVX-1j9f?vk>!!re|W# zZTYBl7t}OIzekqOIxOV3!c`fgDr@bym*(Alv>}!0y;j02Qlp+wD%uI<^nZ7CStun+ z&jn0@Zf;->_foDy$fn!f!zxI#yRjq$3+SkT_?G=(w%ARn8rq&c{*Y<@^Azv_S(nwh_c=%70a&n0UF>&H`<-gMr;o)vo!A^p%FJSs&brb7U+3*jgA z=LGs0r1 zW&Hc!VZ^#j{l@phE%-Pe&`5%JOKjHC04q|rFk5ETsWd+2hl|3H@iC1!zd{s0y{MN_iGZLUr#Fh$ z)w!*LC|v)fqr^Kfg>6qQoCdU8(j+)g11%-ee_)-tHYmnfM(;m*!cc?H-0?74V=8M? zL^4Ctr|r~(I*a9{n_YTPdxaP6P7?!mq>2zRkOKUcg}CU=kCr%XKM<5MH`*NQ%<_9X zF=f*UlehDYaF<48%*AY0FOQ>d?Kp(5?R>d=ujLzC4mvWq6m;2i-rj-Ai9_A~Gm)sP zjT(l@^wxFDk`NfO$-hwDELtpfKQwS2WE(xzj7(Sq{b$~b#;WUrv!WEx@K*g4&@aig^%|t z^RDAlT*>>L0I$JzwX-@ZGUfBw3ZCt5osp^N(->aH9-#%B7x^2~KtlXQml znjCr!0{);j+Rt?*z{P^#=;>W)so-gqU*)V)Vp~NG`~v)fuk>hXJdSfUB_uucOlsO& zb8?Y>f-NJEHyF!nyK%#LffjLBkHb~b)T{)MbEu?_{l?G1wy!uQyHcQwH76 z=op_#?`=Z$bZ#9+0;30qQ3hcz-mM_@)6i*|n63gH@E-F;e(9^V{$zpWB;7&{CEB!D zN&YgYbFL&*9lUw;dXpeCH8-u6z5KseK)Q%-J+>{{z?q}jbJvpZseGpje)-Ol{tf_V zR~aw2j5i;a0)bLNNGdBlORIjnlgVNjZ%pU;k2 z*nL3bzcEITnS8!OL+f=m0=6Ba0bJxj8XDHjRBM7o5AbuiAa;whZ1E1j-I-`fKvtIM z#c)bnFx-*C_a3###b7kcxT@+^0cx)tNyBG3ysf=>Yi*%e$!~aspcYWZ!LPp&MKrml zFBCMa4~(uq%ZKJ}?Km9=RM9xLxnSRT1?Shi>5aW^SL{D81|0e%g;v<@Rmui2sh;Zm zu^&WzvW>+D9j<3dkWGGcl{%kPoVM7!LxlOG!kU4htWCUjysB;GvYq8!PAz3F0HwaB zczB#Yx(eBrK<5xe>bKfX!?!PAOk3gM{bBZ#BnCvU(Q=S&xXE%2Mwl5I&0mj%7Na?X zO`^oibm3eG6Se1}=J9o#NT#ij0W9iwwp&gBHm2IZ$EHlbGr{!3k6-Q&0A53}!n`Ow z^G-mZ)xwkfS?(Y;2P1FqpF^QZJr~u949!ub6e~2vq@jxwmt=$epgoDE=Q9wa9DR{% zMt;#h>q)9v@z=qRn{nDQVW*j2fAR_$xEUBoz?1nj|Fu!j0@oS@EPfuQN=t0&N`;X~ z3cnwk<33tVKz%N@VHxuHk(m4DGvBt|pqjbm&D`cFBb)pv8rQmAvvcdIZAub_;II-d zADSwIFWv33F|oo9Dh@~I?puFi7~)WKWwhjvO{DGx z(7EN%VG!;(^%fPcy4UQy9L|a4f(++ACD44%0(CY&Dq`sgjkFF1Ta!PTm=^j@6d9`D z^VYg_b%9f{^F5E|9LY-!)fOqI+KIcL71;E@<0KJm=OmxtxNSFcco94ITeY*`OQ1H5 znEUoy3=hgWf83crwNB6YzHXbM86Tb3+!f3rJNktne=YaLTm8~KW6niZzB@d=}v$dD5pjr>Q!;_h5 z0Qk4XLBvY-Sc8T?r^w`MNZw+oJEm}s71RvTB6qFd=$f29kA83B6K=nwouGJ#l1gt# z*5>PYY;qkl%YMERBYTXQ?u>pe!8u5w-)wlfc<@C7mTk|FTS|pkAButYWyDbWSsjLv zUH3RPC%JAxXbP{ryqTIVl&UYovljr#qP#VTfYNi{6oG&U+wxvh@7^6qSM_6<^=59N zRO=?z;dUwn&v6>g&_jE%Up#5jMDOZR$NN^(#^SgFW)NQDeD&~4#}|N4;E~RRBA3L} zb(j?5dNuubm0|Ql>>1%;jd8D#l+VJ^X<6{J>E09$F%8JPtnK#Cy6(yH)7n;UFe@g z$;60Wp|dTz&e-pd+ZdI}>+Vjq6W9CgS2ND(pvcA6rEVT?yY_GSAu3 z1<;|^AniNa?nE+w(rr_pud=vLv&H(PD2hTFe=x}QbPWAoE}!k~FX&cvPl7q)UWx>d zF|Fv7$AlRg<#GKSU{gGB!aop8)@Zq_oYk@#X5+0in)VVqvpc;|hA}h2YwX>R=nN#Ycm7=Hp z9Vfsj2#{A{NY}MXagoKmh`=MzUc_8F#A>oBUlk#~xx>)FwfFTIwP3(5HEp5Gj29yW zi?*hPl1m}6pGqW~G$mcWC5tW>Q{1WUEkO%mo#nR*aat_HTW1C>z@gOnsA7%5pj!Gt z&zA$D=jE|m8t2;tg>#Mcd%5{QTlN&;&Ft~C!Y-*N`sSZHqbSYlozO>8zIT2|iXJCH z`*aJotcko*$Ao$JFwEh?lB6aogEfT(j)v!$Ni(!O%9pF&%e6%DgGw@vYR_+Vr z4{#!Sjph2$N(C^@Cx@E{;c4JtvXo3YX~HLbl-kLh8N^vq*Q6zqlO!5&qT8!;$Xa@M zRcAH6ibnVMCPD;`tM2Enx=aQ2!`({*hRQc{k<3!leq2bwApBznTF7-ICA~j3iXrhw zc8_v0`5w<3S3WsS@Sg;0-EzmhbZ?K&3jrJ~C7yIYiS`;6MS`5A9Vsah1C9u%3mP=I>uI!@eFD?Zm8eC z3-DUdkA^|9U-d=a45wa?kBC7qD-^+*+H9-yK?{xxtA-tU8p$OOS?v1<=hIC&5hnUU zCnvetZOmq3j;nPfPw%jLBuSlJcsW0|G=g6d`3wZQD%x-Mt(k#Q+1fcjfRleJ1_0h` z`iSdy{wYe70&X3Bp>1s?KFSj)2^S9qH>`NC}ODt|n;9JLO8S?t|CRS%yR_o8>zexk9;a;jP@I#`s z(&i)l66n>&6$TBZ4BD~mH3NHw!C^;#k5|29=j=sdSw98ID*WtZ$#JPC%CkYv!)gcZ zr9a$rKmB5YBN}~C4{beuSC*Zqq{et9L8xt@=VdqO~=ZV*b=GC(;Y*_ zlIH5lSr;)#eETRn4i5!a;m5&52}58vL`ibP2)GnSIM4|0q|O-RXjdHsm32z ztSoJ+fhDpQl?yYaPSVJ`q#h@rnbji`uPc14lj<5z>aX}-(>|Y$u~nuKvs~>n)*Wr* zP=x#Lb|b8PB#v(5y(cdMG`F=t?VA?zT()iS0#%R5RE1z7Y^z<4LK@9$y&BP+AK@}t z;>!tT6or6^IU&q|{)NA5pvuB^qL3haTG2wC)%l8)mCqI)1-9NqHBSzL%`1n6MtZrAL5J^Jg`QdSnUiSef3 zpG!U6w#JYg-wR8-YwyA!u4G$?C&~x(`B}|5Dtc+f zB!7K}m@bq%a>u1~T;Fu3tkS2hS$yO1O(U1_1~&=b<yD=j_PfKcn(R#8jmoU?y@#=seYf6V@ z!Sb2==oS|!D~DarpIyqQ&9RcBw&JxWoLoHo(0 zU*$#UVr(L~IK4)0#p?RgK{Pe3ZZ((*^n$w=`tgey7K!ob$ftBTbq(-eJlrBm&aKo- z9NRHM|7kOp%`!bfYS-@&?)jdK>il)z?b`_uXNXSbX0*pO%znRR4vFWi0a?Kg8kp#H5*N3do?ku%iFeu=%)-iS5u?X39~8C@q*de8$~S z645Q{vRYX8qaZ0#%Dn}q{OXCOs6zfZBR~pVB4)&zEOIVjD>yQ zcRI@MFEH2_IXk|!HD{w{T`D2BAf1LcPX%?~cpJFM&n8S1>&RaXI2(KIv>;|;B^r_L zR1}B*$atWl%D8G&M_)y!J+qIGH>4G!H-3(NyErn0uQ}$aB>-X4eJ-ylP?-j~%1gXbwN2sQ{qWQRq`qkW3PhKb+ zt=YbeM(%7p+VS@t*lIlT+5U z6Qhk|x^(3Cvj)8Sbx zy|%%dnoz^BC2el`VYnWGas;iU=GPXyE^PZR7T`vr$jZz)4W{M~dnepm_goJ_|GP zi>nok?QY=ZxMrABj4ba6)zj?$^sKr|jG@%)SOs;2ORe_Vmqw?~CLs!VB9O#qy0Y+< zQma{mwQcsg6nJ;GaBaccI=!5m4f^fy?oEr|Y0B|sfRV}?ev=Ya>oFL^!jzi%pdeGX zUOH8kXCjQVfTqJwk;ce+r}MX}RpZHmyu};*GHEQXm}aEJB1gNA?ZGsm5FBeC6TjP? zvMS+7E``Wv+#O+Aws;@}Z#lba+23s~JK5LY3!;>Z-)Tkd79hS5FkzIS&g1h3SiPjZf!d@#}9<#n~g$}qDVI^$9Vl}JRh30<<%k0lt8BcAYAs$#MS=6 z*^seOC9cCmmQ7Um4Eu<63E1ksABsE>WbTxy(Jz~0a{+M#*nQXjXDb2wr^jy?*wwt} z?o?V8Ci`kpwxtT!ABkEs+;V?s_L3xi{FNAd7_S@p&~JE44;Vi>^+lXHtVB*onTm(q z?73iQnCLLIJU+|#++4n7(em*LZoV-8j%IMn>Selj_SsscpEapd#l)*1O#N8^V!iqY zp4$iQZBFfh^zD{f2c|BXGOYpVb~SvMbe}G(%n;XeVK)8@qZ4L|ulhov-|&W!-DKsZ zoKJy|eX2B`<&oWqurLf=-?`s~GElHm4<{WrSbP`Cxz4A4i+1zM52r7@ugP!wprxVZ zPW5mHYd@q~Nrq@JQs%{wW%#A*5K|M=!NoYwBdP(`0WV8sF_SETmAEmRn%&IVJ94k> zrg!(VEl`!`GR{9lL#P(=85ZwypK z?UbUV7(X%&pZ>G?`&Woq)#VRglvSgo@|6j?aH~ObmUKURpyKb~nnj1KJ&)DtB@Bw1 z0`FfO#u+f-D~1!fBSGkoO4f&X>-J3Zk31=UT<<>p+q>YC*!hvIgwnxN zXEed(h1U*y9BGA#d&^*)RPLoRa+UdJ>bm|;okw=Rw6I_!cEot$opx=Pn$xk_C$kNn zEuz4AjS0d?01IAy2PE~jFK$??$3~!e^()@ z_QgHLS6^L9L|<3<>29y@TNfWz|6YlfPZ1WX#qGR`V9c-Bo3qN&q!!kE*`A=;uQKj+ zbgQE`)9k9V`HQD7I4f4Ftc~d-!0*6?Uw){o5fbG3ra(L0QKz+!0t5#8$yn~mFE=#q zaWp$y*>Wmw^g>CJFkRu5PFHAbKNm=(=um=Htl5E*cdg7w()OtF?1%Hed(#I%^x5z+ z`LCUwmINBoI8>LdeQM1zkS9o8wrEr_45$z$=QfejjvoBILLuL3!GpD|YMad_xNF}| zX3xWPf8*y|KXKT>`%4syY`Z@YPx* zM9SZ|vl8D>o4FOpy6X9z!) zYx$b`VEl0I!q=__cgiY=&COfIIPIkylHEAJkk<--7ElpSV9}vj%73&}@yO!XYiCUd z)22c7`l=Swhxs6C?ob(**RN+_P8i1D^Xt3$r1~!>Z@mp00i6 zWYnfhKj zdGPyZBrIixX0;`H;+RGwe>FMK%gpnXtE;uAznAPojDK zhUAQC?m(Y{siQh!izlJCb|C3N*&Kai_VM#BJ3sWvQ-3R2zPrq8tQ?HStia_#?RSxC zD0h|TBDV9`IGxx>sNP-R4{=avxXvsp+zd9LrAPTRiI{~f0DT#oR1-hO$Ygre^$}T^ zANDc5t@S(Gfq0eGbHC2Z#!1@_rF=1*l4)hEvF|k~Def?r(>a+SG!_?;qKWXG`w;v{ zGYEe)v+R-kvtH5+3!ewdqvHj3pLhU^-FWIRv3GSo8eOaemWDgi+a1BA=4q3l3*7v3&z{hGOL{C2 z0wZ;I;a)wTBW}giSJO~01le>8^$-e3!t5X)g!PB`^1ApcX=909%^(Y=t~Nq?v0mNF zE@J+0w5}oIllUGsy8MFm5-=U_F$Z1re47cAaLf$4 zN}~-5uyzJ}FGY1yv>1-SspN_Dppy_Mk&Hq;)w=%d$5elO4<4pKO6dD_=F-&yfWH|4NPB+Ij0*+2wHj zuX2&X0JbQD`z^97Y4Y&rEv*UZB3rCg=eG36M_4Jx{2?Ne>n2(8x5R_Cp{ycm3^? zD(0=dot((~BmLtx&Arb|ub#w`#-&ryIsIZ$9>y+x?2~79&f&bMlSee}?KmCU`=7_s zy&9=qofo@0ogZ)NhHB_(yol3rN%lGH8iDSmA0MfBsD(klGs|lx3)y~j?r*EPT7&yI zqBgqSR$J-)0~~ypH*CH%yumuPUj)wBYiR^F8QeA(8pt2RsqV@1rblU=h@$Rfu%b=F z)3^#ac3E868DW!yBf9QZ;Kt=QT5(rp7TCs#E2w>T#Ih}B=iwKI}`N>j1-5Y5zhNx z{u0xSHvbYq8NO<*2Wx)YQ6|skoFv6txCm41e&!53z2vBQ;oBY0bJ4;7X)Ubyl&cA!FqGh>myCH?pg@&=x4yTyDfG_(DmWi4CI2aeR zmGGThas@nW!x>T^L>e|E2u-a@0zBVBLK|~S6G?rhv4@;B6=wX)6;Q&6`&dRzYHGgS zOeysl^koD!IZQ9!dlJUdEl}Q~)k~|w8#~ari+ymv_8(hz{osc{b%2JEj;)*-bCa_T|+*)r22CADpv@yO*Lq&+`*_d!u%+9&BkAO;V}}nvas5=5 z`lgm~*@=;ThLxI9R1M07B~gcD=}}HjQFWcEby}k@vI+YNXsR6aVfs5edwYIl6x+i7 zZoziWoh*2rlj3|J{-Z4s)PhUu_6p-Np z-*{QXMFe0Lnr`xr;n#1+c^^{pbfwn?IGdRVO;r0F!ie}8tqa0oL*faLjd} z_)c-&VR%G(r`+HP@$9<+bG3#ce{ZRBa`WMI(I?uaYF!C!zyHw=RAM3Pv2NX7&VeK- z(Xh_ECI<8^MQ0HP7Bn;?+w#5N&*^#UP{k&4vO+63(zpdA=Ikn8mpj*aTa=b_`#bol zK$SI#6j+S798_V!k{-sv{iAn=h+nWwYm#Mdvi8x>y-aa`Jf^0psv4;gqbfmpXC&_) zFvv}PvO`X!*=bd@bS<#wdYDaq_>Zq;Ur{3j>*vyTd*U)Z@l!16a|>bto94A)uSe=W zDv`w_GqB%Dei*DrB{g3jLI_A+HlZ9#N+0^AvdsY8XGO~hV36-PSv(m>TL7NWu*lT3Q^=@2XNe-k+3gyS9I;>yi|NiBhX!Bsyn7@x<4a7FE!K}z z{V4{ESU8~V)_Dm*jl2lqIp0wwSxl6M*K+On#OsUQOmq9Zx1X5ZU0|Dk{)+`n^(Bze zzlNLJXi0tIPIImwX$z+JxNP`tNe%s)7cq=)`fJlYi~Jt2{2%WhETTOIKpj6%tfQvn zF!#P1P_-viXu2rQGG5(^83Ev z{7C=E`L_sA-hTS3&UN7;K;zKOEJ8WwQS49#Mo`1Dl4nv`dC~nI|MchiXPncIeO~=U zvZ0A4O)^AYwbeUYz6r3g$;)<<)i&*A4r8RTC7yFr+BF(|MXAysp{!6lw zc5~ZAC`Ig&j*d5h4Xy zdd3#JaxZHWb{7Cte11A%Z~l2iCB##n&FbX~g!8*Q_`w(>C`lBl9z*I1M{L*z1cIZx zzqvyL;@Bde#pyL7ib&>8L}eUMCU2Tu2XEDoxz6ci3SyfM+*D-ZmhdB=Kb?0+^%>N2 z6bc5#j*N~Zi@I2u0FMQfs}okXrL+Ld5wgq=?^DFCE&8*@F-IyTrnz-B+*fu^rvXAC z%NoFrT6@YjJsh$}T@ms1em*@YVc@#}9l5l-QvQpHCc3lMB(a_{DwI+JztZDIi#g$| zBX^i|&i}DIn1~cBm*pLmb9+{aOQdxHZl1hnH7R_ZCUsdaGFw3y|Vb& z-lg<}_@%;^(11Y!=8^~PSnBo|Kvkj2>~-QdLSju*rgP}gezMiU^_NhLYdCYT(zuW( z3E3@+`N4Q?g^+-v2xC?$LH$ygJ_h6S4;wRi6#rM(PeAod{m%AkiKRa;c&y^qynpy& zAM@1Rv2~^?cQCgh2vMj_=~YpyJC|s;L3X$1R8z^ig&I>1F2~%R%%^T!UZx+Rz+zN% zfAy>-1&u!(e?S@egf-%Lvj^h=x?b^)K?DM|ol8Ll<-TprBD$;B2QAcW z>iO+t1prM6wV*R<+P>?Z8aCT|9*vl>I?~7#C`W4C6Z;5do|!CPkv5Za)Kah``lQV7 zvW_yk@8V)k#ieWx;oaTl|DdcKZt|hw5Z?{zK?A-t?Vl99~ImBC@Uck|kHeuI0Q6q=WEjYsKOMbL0&q1tye zt)ICUz1a??AdH_MKrn0S$9e1;T^1|7Cc#^sYByAK4yZ?qk|2 zkPEGsJ)%!2885?ll=SL7Z=HKgk;d{^=dD>#chHe^{?=bTZ%Sex`1s$7lMm$_SnZ6g z5Ex)M(|QSL9x84I--pl3jod2-jMa@19zPchcIRnHs?jX^>bbnz%$TX@h#!8FU!?NH3+Mxfsp|ngO9>lunN81ZwxH@%T!o~}ACfWy2K|G^anz>%-^0S-jNj@k ze>LLfsaSR9>Q;K1>fDNY`s72-VBF~pjmvPyG4Ev|4nghw%ZC)lc4i@yAvsNz6!#s= zmIjEB#sx(>jKSfOnpY8uGt{tA%^Ls{^Y0L3{6D+{HJ%;$=f55^?55pm6L`L{*t+$jYDQHws0fim+g`Lbe!3un)1#l5&R#xC+mx%qlnx!`vqZ-Ub*HPVErNT`1)IC6 z3|H!U{ejQmri$}lxY8`@5&5f^ix@OJugIG{PS=58t&aN2d2cN2jkZc?nd`UHnbWNG zB^I;5GF)?W#($fu_biiH*MFyDMG?L=8eG8_ElSiaRy=tr>mM2Mt}WT9 zHGzwXvyhX@|DuZ=zxo+ia8m{7KUEaStdltshrA&FAey~-X*np8q<K^2gXM$G|fV zHYvt#Mrv^Wr+6TA{jGIv^c<5)(N@9yJPujX{#~_ou<0YOQWsKPg7CK)TBotuuQE7M z>Cizqh0vw$+0grYPpH0|r0!X@taC(s=Em( z+Cb}HB=TZ($0aKzbZJ7{!mnxMlV0Hy^IJGtZOXOnlF!|6E_SdAX@`W%NAoJtvl`)G zvQIclm~oFBnV~`-dz}#%w>8FUt!aA23}JECh&!FEb70EL;3o7S%9{3q3)~G@fBx^V zZ^6Zg-WjDQiz`K_lXpL%mz0yk&-hfGZSt_Jh=fTXXFqRB=jBxf7hG)X&RhJAcy`hv z$0_^7>rxSl76%j~I{~-r)6$wymGBYE6LztijqNGxIeCepI`;1CKfraoR4yH->MI7OUMjt z+swXSf|7u^{0<53dR_ibN|j_WZ)6G$EX={>+{l}b4G_)U`}{#PhLm%K^{sqMbry4o zG@f1L^T!OhWzrJS)6-*Ne|)2HdX$%bc=s20(m-NK{6v3ZPG-ut+E(sgm) z8OAC+45tWD&&koilb)2r$DPlr=J;VVM2O&`^cg?LcDd{8UN8N=XB4o8aGnmG#s+V-~9Y$=>Z9z-)t!0 zNeRU*z|9oYaD7;_{M5;Rg3IjeWL2lppn#hH7)rQml4ygI^#?n_gAn5wo>MNNOq0uf zG4OoIy}2Q33Qi?ckF{3z(G)Hce)j>`MJE#@bNkflHMq9C;@uoI;ey1_3?Wl=GbW}{ zSD`)B(zrC!4E72+Hq$)W9^DKchOunuSi1z}5Br{_G@Bu9$aO~IZL>0r;&jt^8REf!!QQnfr@47_1H{(;ZoE$r|U?3kv6}X7jGqtslFg*A9Q{F zluCyS0h#ZQ3z3@&tB2K|jSKj1t`wwUwwEW7VQdk@EDA9fyRpHgL{m$g{#L&tVwABL z%J*@RI|EKVK=@hRqx{=zcbavTc1)iT;FcLau^LhOEf5!03oo}-~mV57b2kLE%w zCa(D;PEoC@y4lD0&%+NZm_W)&bAgtrZ#3j&|4+cP!Z`ynS5mSUy~EwG@a=n;MEfea zS>X*UgU%jre#vRe;tYDXTDBl@xqHjQkt?3Zau^m7=0nk!TxXZRgH~L%q5^^sb!M$k z2NRM^aMZ`p=j&&s;*FBqv2+}BKdcu`eXcIguT2{&rd~0&fUkSniA=<{QWEm-*z~u! z6#Y8f2PYXD_7Xvwe_M$Bf!)XgsYSam|Ep{koX%kw`o|F|FBcK}nAM0n15}<}=(xu%tgK zCy)t!un3kPQPz0}<1vceX2RT!{4iwGbMe-6;DdxQtrI(i+ajIHIOm+vQF{-^T_%h% zn;~r?FYkph(VkFe9&<2J>eX0kQsr~22o0eLnl35(t-h`6KfxbIIwHAOD*eE7A6j!@ znhX8BMBQqxOi!r3L?{Wam6_neE#qr!oLz#;r`eEEE@m0|pEZEi=Gqzk2C&6BO`(;BZ9{`y5uTVUH&jfWJBnY0WOJ zvxW3i*r-{p1k)H-(sK!U{+aIc!bLNdHfkt6p*um(>bS`|sQ5WFa6eSntYcQS&Pwz~ zKaI16e%-7_ zL4O@Tzw|X7&()n+Mk#TlWJ1>Xkm>S*9x7m|vf%G$FS6pV3W;82rnlw`|wjcTCHa8cS_h|5XH#^+|xT#*ruCy->n|Q^N zrDUdqGvVb*Km6#>GizA;WMix9C#CG4B$D)bU9XN*B4YPOTG^^@nJVn0cX&whFg~J5 zA!U>^Rld4<;6Z)RZq~pwi6f++88g1=bZDw`udR@#?vTm1(+lvm$JdyvTK6<~78ezd z+7mj}k=6e>%lj%wXzz6)v|DSfmX`Qr1q>Nx;L`y#Yh;552kwjvbyF_J#&i4Ws8A>I z>6s0C3j1hQbr*OlMD>L~u(NKl zV#iZDqk;gNcfXfEG`pVhb?@x>7&dVckm@dp{dshjgGwPQ=!wlyaplt8Ys*SLT_a-h zm)}sXfle0ks;zr%bnKrsd_9tfz(@3OK}$@IXb&@^hRrK*bbuh20+*cp06{cYADa_4 zH*qDPX{V#}8vTpEQ5)1$YG0(24t(f_Q>Wh57XezB>C_tLmW=A~0$vA=V7WB7fW8Wq z8sAesYb}yrp5azB{cgDrWqBD%%$wW$cTLgX-W=eg9Kv!73qo^XPe)z?Y#%;NIL6&G zcoLPzoVj)0*}5JAGG}tWGm+8kR2122NfF6i<{OR1FSDs!tk*FC4#aym@$63f{l_vliU5-{zD$jJg9$yo z7S0BFS@TgJeiyQsHIL4|y$m5SE z!6ItZIP*L7zcr5R?QhC?a<7-KZb=gj7t32T2=|@U+?3Ssw3y%3!38zoNfZ4q>fSOa zt}X~0BqTwDB!rNlAp{SQ1b26WyM_<~gS$%z7J|FG>)e}#&l~=AtUAgYogX?eP}wEbFSM0nd={Q1$YJM@;Bx zP(q+AknSx@q?2VF=~1$G2EKVB-Sp5j|8?dw{D-atZQqgp+=j!{M>@*M_a3lE$ru9* zTZZesUQr{BUf)|Yj8m3-VPjw%DL#_;@2K(r)^S&Rn<7M{26=}t;kkp{{!92OpX_s{ zk>2IA6*ltv5Hl;aCx+i*G*$6equitpyFLJ$Z*dq?t?d2?iI7d|>hfH4l_Ze()waJw zw2F3bQ?VY=Ts^rK9aETXsEN4M{FJQ-WWe}0*uBr=0jk=2_jWb8()mi=uKh*%bqR%( zGo)xo_?`EbhKix^-;(x|gtnwR=abrWa+bwk4)yecSa zAoN+WC(Cl{{Z$ax%8UG&;bCya)bZDZ3BLbu*qG})Q)PdS(kHd8rJC)kh! zIBT}8Wxyy+{Yl5mfzi8>n}xGsZ6WVzkHcT4?fZ*FV>V(}-kxC7F(mgeb!WLF=gN7nMW#-F%&QAm zHd(E|E1Y+F!#LV(x+-LPy)v!GCSoycJ8OC#$7a8(Lmn@*!!X|FV6A2{8Fr@#LLFCAEkPwfK{6MT))tWsj2;d>2x8 zp&L+X``OF)3|fouf+zBdNl2tkPg0lPaj$2rJjr3Upt6nUMsUMpU|~jDL}s5tx<+Wo zKq9SX8v%Ioa##;AI#kAOZr(~ZPc{Nxf9B)<5j}wZ?XPTnu%SoK))k-(oHVOvLx(3f z?vuTmK1jKS+?<>o7#OW0Yx{v^6)M!No0P7Rp5fR>cY=2=+TPj6J24d9&f86G)b;g~ z-4tmZIIHQmwj0d)JSi*3X~1B7xsBatB+}Vlj!pOK*4sdF_#$1}LP{k?@G#_wk+^cz z%a8x&PwYfu&^;j`Dw93mmRN>5^^x1f(nwh2yho#KW&9MQ5sxLJIPal^x@0?9;D5-YBS>3K}-Lx@FjFPVLI_x>@1( zBm%SABO>*JZP81-I!Q$<4tr36RWnyLu$z7Zmlpg@3L1P z7?xz;wl})pNPd3GVLkZ38NcmOrH@{SxcfV=&G}OGzAQxc^F?}QT`PMio*2ixRq|wO zkFaO3^p{#a-A|7f_4u<0;;JGo$`<0A*vi}QvY(i3Q#BD*F2u3+6IeR)dk^+&v4W`` zFP0f)ey#nA9IqHDwKfAu_Pe?RT<5wWnQ!%16^*Su8A7p|piCC6O_&{IdY|96^|VxS z11jL_>FjxsbawNJd4rR&i2ku68&*#eWJr=7-f;Zs$j zIt#Fdi&qmrm@CEIhPRtMk$)LazMKFb^U%qw-TIb%vKjNzdIu#TIg~Tq8wXxj|`eM9p zo6(RTB=$AKklX4i^QAhcZ2#hU*ZD~1p|-N_5lni6o#Itf>DK2NWOVx!rnbRKK!*LC zO?`A4mpypptm^g-zSQ)@x=P31=^BE(_eGzmpBcuVG=vmt9fd#<#3nrcrs zF=CvWT1|R>n9ee)xr+~;Ru*((h)lb<0C#lY7cthOdUI!v`%^@HK}I!N^#j^R-PU{f zQq`;N&Q}J45IoKh@w#n8hQ{`~k6qd>k)zr%4Rvo^|7{lJ&@7WBWC*-g7vZuLfnfiQ zkf+0XrLt|e9B2JY)vr?;wwm}BHaN5PE8`Od5)msI((hhiW${y9F>*3|i9EgCk>J-j z<#UkWJNpurP4)GdIl&US?!bRPf?GWNcZhffLlnt;k5KbKtpEc?j?Ug#FyrG zpV@7@5m0%r;y{xxfjzBhPb7(kO=#DW?y`O#)1Q|lZ?K8t+r#Ra(TP18tqakT7IF%T zJbxz(#+Eo`(VJFQ1>!Ra+C%BNX;Vn@r<5Q~7R^fAqO+;*CSC1Q(;LSe7epYsR>(cS z{%Y#4eBcrq-Z*q8-JM@d_#Q@61>zBOnxe}Fn;iFN!1w2q-q}9cb=0}-^B(KNc9zXP zpAkQHdR9kjamc@Tuo?&uDWc;y9jpZ#EH|5FMJ~=&ea~yRA6pH+=3w4@;+b>TYF)=M zJQrq!$;{56zMybkUoB9$a=AQj(%ETgSdB4J>|(B(x>O17xE2SEoSoQFFLKq@Kq7o9 z$}1Y6BE2!Jhtw9(>Z9Z$4F(5gY=htibE!k9Mrzg~*Zj13J)h^YEAO(v#lbC9IDR7)vS2==odtQB8?k{p z?dCHlX$Gp*d2V=jq>oZO{n61dY4`R|@Gm@+31jz>;JVerc{L9Zq zmj7oiKv$&m8=|E)_j!EQqzT7a_65>83j*44Yz=W{1Z*-}{K;2^0-UV(XfR1adIMc( z5O~CX4?m9Ab-ZG%{5>fkK|AfJr$rG;ai<}BCVJZ~kaRf%p|_xNVO4$BxMx%UTp(i$ zzdgKj{}3RSnco6P-_CWT3X_H6^6mZ)B}l&owVz0Nbtd0Jw{7-2OL*i3M;i6*?1{<{ zZCzycBDscM)cq=|uJz_ZU^ot%zlpl>sc7i_Sq?eU6i~dFS6t8`nJzmX+L_hf7pDE7%qrWvi4DgWSznlE*erZ71X< zihYRHbS94!8haYXQK#JIOv&@EbL>?M|Mv%5f(!| zq_3O9=%AyJ&Owh$Q!LT8Ph@iu$O6^oNgA!>LE)Nu@G!l8l9HyYEj=|mQXpj+_@*1@F&Yl;uz zR&$3lhU~D^qLaog0u{Bw6oF&ZRrlkN2sJDNJ3mhYwc@~HrTWW>=K4uTr|^!uo~2$V z`J-5VQ2ti-VP4Xz)^K$6E4KLyg(jh{uNq;df55O$io=wjbs^eeDyuUHOTYe}n5RRN ze`dibx?yVnGuxAop;5|H=1uLBY~w4=Bs|JAp73TUC!btx~ z@4dgi(+(MjO--N0SE;mc=ZpFzTER|)hRlgR7h}h_VTyFc{Atc!pi&A(+R$FWFUs0> z`U}L1a#ORiMK=FT6E3e+MDUb0PrL;jNKp3=r4Mg8)t{5Sm~D*xAXHq4uo2jum!y!I zMuE>~lwb0m#9q-!$$0$)-Gm57(&aVOrzZW_2#t7Ydql`mCkn0~{Z#3RW;FN(?y51x zdB`7_YC|%x%y$t++rS+EC5RdPXJ)RKej`V1Bgk~wd@v3nwo`ia?Wg?k2r)t65GB(o zPr!e5GNSJp+eHp*O;n8P5Gy=A>4pY&>nT6F`CLZ$40>}udbblb4MI1NuA!1~SK4J@qd@>@p)2sJF4G?=C_JvZ`X-26)JVWR5TKq zt;fonga8MbE(f5exM|l2nO2*x(oeA$6lf8k%WH?8k7R<)n~ zB66CewA=xWN@F)N%ggJ;3-k(%`MvI1n6cs=a^bI6IzAnE$q9@7aAgnmn@?-+Z_-J- zke?gGjhEVEY3gX)r0=!m{i>`~2XKGeHd9^ugf-tpD2>X+o-DL}qG;6o)x0*y8wC`_ zg&XQjbcYUmeiW7$XjJp_h>~ZC&K58?wvtJswKkCTp9!4WOs=Cs4J=iRO1tI%Z3m>e zBl)F3n9YARE)wVmxd?-LE!LOI{tXqxhd#qt!xpGVaK0@pd=~WAbN!!Sn2#bO^;q^ecbeJ%=(IVHQ{9HUlSe7h}Sf(>dQFUxKNk8 zXLjR5MY1ld6z`Qyd6KP{=YuC;c7$Q^H1*Q!BzxW3x1$aa*ZBUhspUk))!Q=7pBgY* zlmlla*$0hnk&k_x9q1KozY~4&^uyeP-~IMZ#YA!!A_kM!!Qmv-shoC0nnu#7q~xUb zj?tO^pS5q^Zd^-e1?;gnt@_DdRpSm3^!{uki#S>~IUnpL;-ZLLHf}yfs1$Q_iWA!J zE#cX-O%bIwevXAL6Q7(9SO~YB&G@9tzY29j`tV!$)go4Y5b}7y+;B&*lY~(bDejQ7 z_^KF+vM(FFm|`@=|5dzUbZxe==ijGPz8eSs->irFKi5g^3K0acH0W2Vm20x(s^egY z9m3q&645Oy?8UuI(;GsJam_PcG`Zu%_juv_!FPW? z(I#KmWTULe$FfP#A|>W`bPR8#a$9e9d9ck5#&2kbJwzmuPxLRgEVq8+PmDE_gsfPr zhNJV6W6}HbM49%G&XYI9Lu`4oI}2|xztgDmgp)U1JjY*GxgQ@Y0B-b!i4d2~un-tX zVI0{z2{^SG_1M3mg@^#SY%M|~+&OX@{s1G(tPnP=_r&7C|9D^UB02NuJm>L5)!Nz` zyaWzUf&cz3_JF7fV&sYZdKE?jw8rU?%>(}O^CDtn$^C~IZR-|o7>9EQod4rH<;$n)KEj z66NWPTwX=D_%_S_dy%ys2f)c`8dco+PC$)^&q&G#a3}HtADid}Jff@X`hqdbr*@;E z;woC`BYIu-$B!S61S*=FFW0Z4Z>`U))-{kXCP7W%od@r1ZpO&SGZh#I)3G0P(b``v zyQMq0-4UhQ(&*RUv>k4v4uv6&wj{n|{Lu5vjhKR2MPZi&&8PqtS{O;liCs7&o8XF_ z#XN;PE662)CDT}>nRWs%d1bd&&+yz!%VLZi1u;P(A^csW@VH;Ueo@%9AD54sG<4`L z<%rW%UA=c*6ANHpJUS%c^gm;*TYTpug;I0Uwao+Xwb(+hepk-HCEjq;t}m^XXvE>3g)} z=P?f`z@5)hqHHuZX{Xrh{n<_1F!ndvzjlkKGH#yYIb=BqQZ*vKc$@3BmHSXYMB;m0 zM|P`^^7mCRXUZOR@JK);&_BlKD{p2$@y^Z8hIRHpALg=)arh|U2C`rw5AakPRHI&1 zMZGJrz`q}*uR(Dq_Yf14$L{hX+V3=fn^VVrrOpo4jTZD6vDvw~88YH* zHrb>vy|W`1eaE)C;DcJZSgvzfoT6bD^}D_F_pj-^%0LR-w6&N+qP1X&7n!yZG0;;fuL zMX)zPcHAHkOUb6?KUj3Z-3O`)!LEtOnw%GhzK7YY;I{Ln{&cjkF7ht~&CXQ*9G%LFXyd%pSqsz`qEC$Na=V(3z3=^Hei? zAEFN095?)JYILQVp5l1ZMbaA5@P6-kz4SU6kBvUmuz@Xm#karFzId^9t-5qV!u=)J zOX3_OzSmC8xgfOjY!}M)q{2YT#L*5gftT$Zk#iOlMCPg_R)H%;8Q0(p|HWOq8U`jq z5xjR31W5g|sa+$U@XK!IU=<%N}QnRQr>Ih;21WXMt(sJt}`3sDU@Wa9+tfyV8J` zO3Xhb;){qXcWIu>DCu~wOHMpd?MNfwQnF$SMUL|3sqg`hM&ubzB2ND9Fbtk;WYy%* zu#m8e5h$bL{+dShW3KX8kn1Rf-*xS`7Aw@c{R+`ZSBGBZmDN1}F_!J|95T22ok|Nt zPF1Rb=S^HDgYCOcqApgUq8)IU=#Ab+&qbx^r8({6g{n(?`AFk(>ZcY*tCSf@jTbi^ z-scCTE0VAGjh0zlRsTs_QLV^Kh|rT@1uvE>bJ2W3MA$+bt@ebmm2q%S_Qd0k3w^J|#bI#0Nz%u&8(Deq-~lhxMPtJ#8trUGurc5=4ih{< zcicE^j6#?F+HRo~-&Q9)I=b_@=eq8ibaT8>P@Uk&X|m$t><sZ&xUd2HwhrYa;!?vde@IQpKNTLfCi1 zJwq|?0;8$S6Reh~J+9rw_?KWWGiA<(*UM;3{DBG6JMfZwMUNmA6_v2va`T{Q=Ca3O z7g6@}qu^~eep~W@iD=6ol8+}mBdwKBY@t{r$+zONzQ$@0zEQX08?QU|PT0rOQ?pZH zm2#d+YO6@)9PAQhZW|dHnT-*&kGt+~+0GGG%M8@jxZf(@-Ds@U1DZu6Z3E}sh^X-C z>BqNNy%D+A5uh%A!nfsg3oBlD~3? zL5p8l%gacQV(*Gsf@-&u)BcL;ajXfBLO2;h;)ia7%c6}$A6i5fnW8xv1eOF%-CBnc zzWza`mqTjhy1{>7RTO-7NYL_m5vMpDi&9^U($|I3uS|1$;e|11B`?mf&^z-ba2R|V|F zg&@s*X6O76EJ>lz%AI^=zMUInkO9`^9H%RrzF51oo6xJ^6p^|w+5tMP{6Fuoa#S(# zc!1I5eYJo62c^S`auLt=%g=t3#{$XU$1NrD^Wwg|$?JK7)uEqiDxBKEiB1VF*SwBl zFrCPukS#V!d&d3#BcCQ?h3l+rbW&#*^WNwRqb;V$n;md7lbgEF+S=dme&YHa4w)r2 zlOU#po*o$@Nctn#{PA zFRJ*bl(wqt90&T-D&TvZb>9;wVv1TLAO7KoXUp~B^(HOO_9Iky^;lyT<-+~`6_y|o+^L)lBY+Hn<~eUzLDl8g)2o` z(pXqeqCUL+J4*SbowMT>Vn4#g3Bb#=n5IM;*fR7%ibDx!3snfTusVl?Mt@}2-;$@| zY9F3nZ_sN$pmCU`8C)^4tl_Vx-J#=9zYz_QLV4?h9k={o}r@>2)hO1HxVA#tUhS8*uWyTH5z=7G+9 zS4K;Kc(SJPC@!mT@-fzqutt;@(C&oi!;EKbYta~O50{hf6TBF-;xBRg#P{&LW5=PO zv!h(ZfIN!`{bNy=(O}+C-ql7l)Lk}f#l8>+A81VxF1FA+vl}wKn9&oH_Q6K1WZH!Z zT(vHe2{S&=pQMnl38c>QQ}g#6GQLiZK0ny{D?{Yu>wk1f;a!e@Sp%qar%du>UB5Y4 zBkI6luX*{AS657sxBb;ly&OM5+N#O%Aum3Y;Z@o+YIJo2y<~sA-CU?&!a=!!PPA4( zM2yo40e57!Z+!YbxqLmPQ^r;p2~{~sH2rpswv4$D@!seV<9PP+2BN2f8po)tPVTze zU9z~Cdy4Hl4!YsFfH!3g##{y^7xxoPQ`nKeYN^`46iK7Nz_=tN?aA7zpP%;}csh%< z>zXw;2k-sS&cAGIK}(dE92+4Y4fP%El{}T0sY1iZ3cBlZit>2NfV zaY)(esf5WS)|tvL+<6wdGbztd*I8_OqnIx)&B5j8x|6u^kt=XJd?k-dw{g!vCrTlG zJ480>h@kkOHha06*}X38m-|KOH38)j@-K!#$DMBBR>~|}{Z!weDVf*YE{XZ<&F;Ml z65UU>@**zu4as_Mo{N*?#7l@nhRICgzObs@(<6cgo)QxurHHC4Azw|UdZ#lU3nSlD zN}R{7@_0{v5!zn%;UGkh$nMgipxT2~#n-2aF|U0sWBkMl*6Um5(s=};De{#Mh?peLpcauZz zZiy9abcBHDY3PWvNY8ikThPL3tP_%kNhEsE3}U!E&vbydzx$eTK$dxVnQ=#@R|BAc zd=xlA_qKJd`2SbO(NfGGm?XWJZ!lfE1tOK%GL(z^zOahuX=rXZxc&px-;v~pJSrd0 zIIKl*R4`RHQzXa#z{DmG%=-a^$~v|kl@(Jy%}WQwa1BFx8Zziz*K8s3t0w&4__G07 z_siTZt?1iZ_&noShV4t}Aq`mi&mM&Z--W-=mszWmMq6zIm)}2eP3KprKX~QnV<2AN zb3eKA)k7&Hv4SkgEiAdx*4BR4e`ap~Q{OhV8m6=mK!%TlOED|TbUC9q$ielR@3n+U ztdSiZ$vM?r{`P$KaY1+1mvO%$%T*{F&tc`iYcRADeQkEq!AfF5NK2Aud(Y+hKHU;L zYbC5_0j}pWBsbEu{H*l7U86EA>`Byn9c>q$lEsQbS3++y=?Pn~l@C?}JAW%J!4g{% zOEJ$I-SVd_{ITcdA4s{io=&zcHg)M<>(#)iwWcBe>q?=JUtUfR4YnqkIpd;NI zHui(E=V8hQ%^eE8ZB2g#~_*>Bqt&_`Sa~~Qr{h{Vy4%9ar^;9gSX*S;e0J%(XRX;H&xA!<1x-rt>b%dRsbYBDjym_i zg0=rx4}bkLb){VRc9wt*G@P1a4SgxGg{$IHQFE}o@m$Q{zgc68i}Qp_VJN6$Ro(p1 zi&r^Qo5DQeQD0`@m*i|X=VD(m{XRVRn$ktIVEdh z*yao~0o{wrXVgFIE2-uPZPin=gTXtR)GjS$qe=0ujpW5FZ~5M{YvMi%$juG3w&hP$ zs8pMF__~Uif``5hkpX4&4X`P=s%L@KL0Y3$@$g8NP8R=Tqx7G69Vf9d9vwz5T5{;$ z*~X+FzXXX)SwYVo`$E&VifetFt6ffU#w`oA-FtOEdL>?!Pu(;#1ex(uAfOSvQ?5)FAV#G-9i2tEw4pi5>o$G-vYl*ulznagb&+1GbGEjb{n z{a$4(wQrl-WRX47Pk%-2SJE4L)9@q-^4&18w*Q_Do7$fG^(*X0WkJKn9`*mkD$C;& zUtH`EIY4&Vw4#2CRZdvC1dyw35RZjC*0f5th31-hZwc4^o{+O&oItp#Qt!_ybe3Hz zp%f%tu7w#*{AKv3ISzARtiq;Or+piwI?}g3F4#9QWhy30yenw|AO}O%4 z9r;!73OkV8{*-SG@@d4Ky{7lGTm`(XCm-tn+s4X)p@IFgs)UDAPCEzU9jox-71zR3 zyY$hWgpFL)oinSe#LeW1U9Qzk|F)IMGwKjN4qf46a1jb>KbP$nir8~kdA>^^O2u{s z_aa^rcY2JBQ55;Bs*gZ8?(JEi0F@MF-|aG(gG_oXhvPtE3de?#33muv+`P6AL`r&5OZuSe=&TlJ8=#8{e@vop8wm>j4)b#mTTPt1(6i68q2+rD6;_~}_12y4Q81+?kdIRRRQKw<{j4F& zdbvD46rRwa38v!G=di76!X0k3oqHvTc{Ym-f_<0x>Gy{?5@Si?HNa!Elwl)KzzIJg zWVNaheE0*aFB6F1m^f#(xF{?&D`)$HA5$a>+ZC6TT2tdR1kmPRV=q|mMb9o!S$#?o zeTYDz#jhyUrj>DSshXH&27)wW@6{k_lcVpiGwypY#Bqjmf$I++XWN3@&h_yngG>CECI1b1K$=C^0|T zjnB5d29g5DEDwj}ls;(|S)g=h1*&4byRRj(6bjU7F|no|PpbK;yuo zG_x1GftG7Lr0F`scE+wtN-HXfHCE(y@X#Qrr}tTVmw`=B=SjRqW~Ahkt`?4WS%mqP z*rE5;TR!7k)u|)r`sLHRHb32zLn|*Y!zyL1%hRm*0Xc{O;3dv8JjSVdj27Az2pZA$YHnwnhMVHs;*XWm1!_Q8kXoE17wQ(=@zA@ZH?pe3d_zHUP8JjEk$mLQl_g!^Hz5 zwAY9Ejo3V&k>9_2AE!eKOceB|J8Nd9)h<~h2fJB?9?<`W=w;VxQi#BTENA0Fipa`!q7w zlG*qyX!`nRE0s2HcN_M7Zf2nwWVSKFDqDzqDN${Fu|X@py0f&jG@8z9VQ%he-%n9s z`r)et^m0+mY=b$7g4Yh9E9YFm0h+P&_$0N1{)o1x%-oA3WRFYkp!=_ z1dYb80E?(M8?`AbZ|$?4^sFiNShlvdOe)Ylf|c_il*9DffP+`d9LTCtQLFZ=YYOl% z`fdQZ73thhA7bPv9wc_L>?|*_Uy90;mX^-;MYY^N2U#dikOXd!6sd{TPK0<t{?q|7h>|bodKyWo)ZifAm#Ofog~= z;@2c@u73ts&ha+tA@-_1is)V;5=BUGf{W$k1}5z^rgAzW+cLND*u^J(tFFnLR<3)m z(B9Av0FSV3Z*kb(iZ=946|;CN9qfB_6ro1Ol}U4%3?#LulheuVlM)h^{RZsG?;kGd zym89YVGPbp=euAvFv=$e$P@EgTU*LtXNWstvzC?Q64PXQ#)dC7mrfhH3uzo$x%#g|&(0n77M6k`V51=; zQBbv>Q}BFYZya@>-|i#>#I|30W|%`vwS7)FGQB>Ptx!n#WLi!<&s`7_FtO#p$EMX| zYVBPU&fb1hry}x6PL9vaZ#5R#gDlG@oqZul<(@7Tiq$6@^tIqm2zGXh@a4d-tvVph zj|jL}@jk2z&*nG#mbpT2(KDrg4;O`V#;Z)0Y27_h2iBTPB8Aekv$L)Ye&@T8vmRNT zppM4@#4F;jrFfs>_?D<(NpLhERSKV4rmK^>w60WDy|qk~sU%WY3}A8PsC9lnVIO7CE{qk_i^j)U@;0xL&jm}ooZs}e`jFdUOMkgXi7!}pgpkZ zs#|tmolC-i>ZaGkd4f1Wa0bj=qO!I;+agPKx;#EYA zE>C+hjM|orkat8Pf3LgHH!HVSU7hAh%Ect`>Y<^bF7_*k3HrQgclUlTQLjo7L)u5z zKkw1iq0K>2^y0YxLfG?B-;+^Z3e?GAw8%A+{W$d`P$YPfTplcXH>lE&_VD@qIY*3@ zg@pxG=eQ91lm8$TT+> zlbSubt@#qZ+5z=%v)%JY-D_1# zO-fH@^m_Jxl--Bdj1I=}`c9*kT zBn&}8K{)mMc!%i3-ZLPbQKX2%@Z_>kx;XHmDjmzJ>U-z z3=g*r4rXx=HP%#SJ_P%r^YA&I!^_BweU2vwXq*Kgttmsm)&%D*qIdFRtC&V_bnxw) zclyCyDEA7VcbfLWA|6C^S-udea?JMH!5 z^8jV_Qcb6}(uY6x&dr-3ftsYmIW#;`gS^-s2@sw$}&lxq%uD1Y{~SoZm)@twmACTO@vb3nQYdK6}@D zRo3l#47+GcXw6K`KrR=*{yIPLQ}zN`m;8g7BJ7_b4KBd8p=DK72Vno3^#6>u{^=_# z*NF+Gsn724H+clT{bdD>QMDyKJ(zx{bW@*`nHO(*@Lidi*;dm99M;kr*nLf+@!y zEq9QH`i#s55v&VX#B+<;nN6QoSu5K>EZNB5PeL8WMOscOmwNj7bv~t^ms8kTwx^1? zz%^7*UH$3lhJEoBG+EDmyVCRQ5w6+oBS@5~d*nrtex={Z*?iy+KFvoMVjR=5n7RGL zRVtKk*YI0QJd6z0!`-ptl(Z+1k{x}PcSk!g4Hry8m4S7qAWwJUSEe2fkY^K@8!2qa@p zS$y9TV?CiP`}frmiYrI{j?02@q6`mjs{exI=xO3x`C@lUqtny8{++^x$9wMv9=8s$ z{h=z_$4egduJcEu+@Y??LXKBK!|4|`8Ky=$Y&Muii7=kgI&P!YjR4OR!0H1jLAda> z#A{88o`#TB@2$X-SbfHwJd&}LQbpw?d;`qR{7-V0@1CK)PN`rO7I_ty8=i}5ACkbc zSeiCcckd#3EubF^nC4Scrukr6vc^@Af%%CONqhb-=$0K5kh;L)Im`r-%wzt(w8RRN z36(yF5!#7+Y-z^+v0*1s3gxph(w@Z}+3#~5QG%|r)-BaR92F(3Wv<*VmP!;{a_q); zU#ANCz0unXY-{-b4ZIBnhJiqnC%{|84>$^Kc;}MMz*T#-_93l=i5;;(!c}}dPe8#_ z;kfPp&K$FI?b$z8gXz?ucm`!WB768JhXtef!|msvpqD**Gah~Yrer4Xfb7HJEt^Rd}j?{F;9X<9WvI5kzIq=MX)gCXo|f($y- zuk$90#}*PC*Ttb_#GkqaSv~^0gMT;9yU3P=yWyS^C%1u?5HH}g5i4GeCEUK75`r+= zCd=!viQBb2ZXh$-F1>hP2mikUKmD)5R{vlB-cf~9<_IT@+G$W@DJ3U1S|@_D_kCD?-Vf;qu_M5k`rNA9ETaL~7G2mg*K$1R}! z|IOs=(s)q`CJ_032NUCrzwr(({2h-KU_6|7(c(GA+L#~7$&zW}Yh)rKCVKaUTO62p zIZd?0S=@vJv4-h-IkKg1NVsSPv^Eeq?@3)*X=*8J-x+Sp2X?2GGdxym)~yuXSx!O_ zKgH~f<5IdqV@hjn*tXrE-P)Q`5(ev0KV}GkaQT;*M^bYc;Y^|?zHJG^?|m)}hJ9Ln zEt_8=BC0tS&2FfH)=~Ci@s%IYP}KI1kTu`4@kc(gi9%AG_HxsbGtY4$jmxLwcLugHx9)McmpWSkN2exln zbmSRwA98K&l>yW^nu_PSAC{QAaEy;QjZ(x^9LNxEcWuV0*ON?Ved2&|`&|rIc7MS~ zDT}P&X4m>79Z-{tDO{F&x$7{mx!?}dRkT{c>~xxPtya21?-~xX?j>-QC?)f2cd2t* zG~_GfV9&Hb7q_*eUOz7Lyb>#Y?Rrm!R%W-k|R=~T@6 z^(lVCWOr8T+1T9;m8}njH2E4VEy8=vo2iq?;7@9_srm^M-^T2#KD&YhIyDvo9-(~y<%mdt7Ef3rsN zK!TLTv#5ug?n^tOlAKR>V+R|-UhG~4)?-;d+&@#IFR}l^_X-Ho=}L&t-ybsDve)Im zg*q-#xgsfxStZCopGCp46KXRTKV}t7mY23)B<*%|^?sD+Xns3h0A-hgLRrMm8 zp7>fb^X3j1VEK>3M?RX;W%j1uhaG>B4K9u; zB%GGPdaCIoH5JjUNs(p?elezl`ud_P=9;FVvsrnuU~l?VcF(9`qqXco%V2oq~4TkRXfhR3KzDtKE>>w0CFB3i@6ev0(imOJf( z1v*Tsv@_F+xE&@YEi_9-agAe)&eq(TnCd!^3L7!`yX8gL5nMQzQ8&=Y-oaa4Qr7P$ z@x%Jyxo0?&Aa=z}_q_HB8wdR~cQ3i>`uq@l?tID3hC;{d%VYI`gItMV5wZM_QdV@m zGql}hA(E6U(@;2czuCV9M zZo}bYg0UmYDXj&QxwS{n1d(}p7)2Gy$w5T)Tx>uo!cw3C)rDT6oeQyzsU~$OlmpIRAs#T_TiJfBzNOv56X<&@YK=EpmO->3w*nY(hqL zd-1PK-zzdtIG22OR;@ddcdJ1z$9rK5&|{%XKCg+v6tUq?T%PQWG01+ zj2Fsq8!Kb*Nj7WW6$hwA7S9bgbi11P&`#Li4g$brRbBSG1|4Ur_x0myM(ghrZyiwf zXjqe*cW*G$7y8jQ$uAr9GB^XNn+^XmX=~J4Lyo>Q=v$!OqP}ww1E`T$lddA+qO}sH zWoE~2P{ZcuaCh^=<*TmZkfd1p-3Bxz`9(PV^Mj0!!U7&!6MUX4mKmHt5ao1&eB=|L zCUZYPNl-PFAUvufIq%t{qlb;Z%+5({UD^EZMtMUB+Ahb?Ez{o9C0e4XU)tG3Ts8); z0Ul&*pWn!K{d){R<5bI^oi4rYa0A4mF7?^}4wPy>sK{|=*5~wqhV~x8qp2Piyh}8X z`(R8$UOKn?=r#*t>aMA?phVvTvUgwiKJ4ncT&O9|)-O@#&Y)um4KUb{*!0Kb>qEGS zp8whK_dDQ!0R7)baul%Hl9jr8swGy3f47^M8H?Bw6=^TgkaYi=#e%54xk*Ey}W z-O)_1{W|~a>41mWC}dB#qoX6{Wx&6G|A1@RBL-;jfuII>(w8X^b?c@Xyqx$spUd3a zLx5S9CFp)o9nSIM`#{x7n~B#>VN()XG6(x!&_GXs*o&Jj|C*W_9n?N75Su7UTk0_u z7T#s#_4RdaEs}&$d4HwtVtQPZm4kx}{^7qq0U7R5G@__}1A9CS;fQ;dyH`*FnOBFZ zHJ|TzbaRGX`X^nso>0t(GhXuf=F&(;!eWS(^PGVprf~HAr+sAdT?hI>d0%Gw<*How z=aopSkRNqCONZBqjdG^Tt_QHs!*PFxO#!rr4aRo^Q3m0PdkDfR!6}V&^#1(87pYvV(56a31|EYT;Bula_q1lU$-uPB7I~I94$Ek5>zrRHV-;sC>kKevkfdPU%?IA6%mL<#L=i zU1fZ)_4B98uuh4diCGk!5~-h@Y|wGN1;UhH@RyMx*1`GlE&^Ig%b=U=;|~uifsjB;Ucq1MfaW7>yrqu%AP{&@HjG{bv|5BPGKMd~dLhTg>y1q9 z^57_IqCCY-?odZ_pC8))edNuPyzIn2>qB&s?<~5aV|6$}W9HP|d9!h`UscO1?)I@LG@b{OIZ5 zG2NAWKodJ$Sz7k~u)cRa2Wb5%#xVs%TT|egM*ZLO%k0JFRUq(~-Y2>X9Cz15_csg^65pa3=i87Inv^4&&pw16!@j3ijb7Mn8KwS$E2Hpjz;@pIp zVRnAwr6Q{;I>9oUovpeScwpk3!2KLc^lty8Keg`1vxZahvtZBz$5`?~K_hi_q>uDIK77za<_5x6a%BT*B%mt4+ zPyGL4L=&7KyS7oU{TQIz%a*vs=pg4efha0xz1_z?1AgzjKudQ1wmVb(>0S8pinCbw zF1=>CWDFn*839LuOhse;H!8O$9sgTr)7yXNiNc0vh(R&RN-H6^2z043jqW4aW z7NXZg!bFX3bipXY=p~3TqDBqT8A5cyJ-+|{^Lu??+*kLxuVxs}vFGe{_Fn5#)=mSs zi^YsCrOW8hR0YXMqAk)bo+QbR>x-Q>*&rYw|EuRenIs%Ct@Gcp^8D#`jPDaBWhL}r zcGW_*NwbrVk&8>{W7&CjR6=ew9R5cKzXGwZX89n0iqLlu5q{u9N+-4$ytM`+XEq>X zn4F%LznHN}`WsfFbN$Y}LBaUSP<{;;GF~ftx)}Bah;oz$3t^;pMy>mP*cvAXM%KNl zb?=hNJ*&7c$N~as{1+VV?qf9l@)Rp$Q}WZb{rF_gygK?@P9>o!op@shw?f{>P#QoA z_9wAF3s7%|1b0y-N#1;YeXi~@EwPwgI&zk0d9_^Jtl@_3EH-gllN+=cm1+?oowzH`yu#w_1vBi_@)ip*RQX_83nV? zpnraK%_3(9<*&+4?VC+6RP~e)!|iiu-WsL{6;n5IuA9pF@4)5JRuKTq90%ZzHd~WB z03_XVxMAE6C}lmapEHS?Qo(+M^o2I57udY*Al0PF29l&PmwSK-=g&X&Na1Eiow4b2 z@40}zZ(+8BbVpI-5k3WfYR9og+!M}E&mt)9_zt!!+waFu%;n6vS+NjBdixEVdI$(l z(c4U#f@b|P=eFP@3+r%Rr+^m@fh}{^(<=1$IIR71>&u7gY+{DoJ>0_G<{JBYRc;(7 zfL<8yz?lNLuS@Z{I300u!Olr~lPzn!KY2p`1#_xZ>5kJ^lO(pv*#1gb?h$hLU+&7x z%&e$Jaqr{X3B>dq0Q4GQ9)PI4i3~vBE5|H3$Jjf+{tZ@iwo^9-6G9oY?eqAxblyt3 z;NR#=u7@uC;e{Atp?{~d!u-aybxJ)X?EeSM?B)T$Ot0jCO}{&`PkO(Y3iffoAiOJf z!5U5mm`xf}m3F@NbdSZ!zJk2U6XJV8MOPa6X>q&qI#Q~_g;718(aw(Pydvl5GGAulvvq|G|MT!QNQmYT?I^ zU2QUuNMzGeAP>Jts@9D7LC#d1V_04e?nELmc-~iMqvVgOr3oAW=o^%{0D;1)5b?io%`b2FJHnpo?=?F@9Ahz> z?5qk$CKjd#JKIrx+&a0wuulo)&Ql6FI2W<)k3LR3RYV@~BEmnYniUgazTHeLL*2aL zbK4F3Ri4z7zV39og5CG;$5_15qtr3YpDLd;%_pA1Q`4ZNi=N1G<@sBV70*eC3cn9I zRK3Hd7VY7dremVp#UeE+7e3s(d&7yTSsq8+(0eSU!hsHX&z#|)yXm6b%om_ zOfq)=y#a^~!+S3=L5!tLzGZZ`vB|1%Orzk26|k42S5W$Ao6BfFpHx4c1~3HiG!V!; zv*D>Z2~#Eb-k29#*UAsd@;V|e+Nr6pp|=?1aWz>eR`1c>Bb&<)BH8{xLP~-2LPZgL zzg3Ni`vvS|oU^gRicwCAlb<6|Z04SK1Mv%@coe4+69)YyS57ZYf?tnJqNq#gJ?;b@ z32|(Pf^(CPtx|R~r}F#zt=!xOw)XIDrORHLJOEiT4&k8~LMVpVxADLCx!0;w3>hp| z^7DPgFdRunLdM`IwefrW#QDP0;yXN6;`(fY{sV~piPWcW3x3}3(|0Po?iNX;$BD!* zE31BKRyvcWqUIHPById8PJvcu})8JP@D1Y)Kx2eMQYR0&MbR(HtM2{xW-iVNiqG)V9ZVc8f^rSh=Gu5mk zJoWAVb0|b>C1Y^(AsagfUNA48;`0Zpz-&Ojv{Miu;@BbtSk5vf*1nS^MPDaQ{k8$U z<9?#C6s+U;NsUFtL7yc-TTax5hlk)SU9C_f@itkT-Xd* zbxm=JI8jcpLZuh;t-X{SjE^T-HNu}J!>!S|QNSVn1RsFK$LVnML0ZDUT=;X4=NOR- zf{Ujo1Qs(+8}0Y+8#3=wM%R`UF+KSHtw5H2LII|KJI2M1(=rI5cuaASTD|CfL^xg= zbH2=#ck%=5ylBHki4`F#*D8@Yf4rO(5&Ia$ZYzuEi{%}VIkQ3 z5#QU&9~?zMa_Jn9LP&C}4++@1S|ebhNn;-0MJ787Di*85C-^7J9yFO2nsY1W;XC?i zlL~lIlnrcdCJ+Nx?wJBK;QzM+-e)oigC^$NmCu&Tt54_2CP-K+M6X{7msNlFT8$kB zZ`Ey2P^$Tv*KtdzaDmXvv!_+qmsjNLF;2pR6Z8}9L2TI!d!~k0%c&QK-aCWPCJ~M& zZ+7jLy^tkbk0+1S6LwOJX9X&li~t26f^GR?_0xOXLbdUO>91z~p@v>(F#-l}Hj6Zs zyR(cq14a&J|8Wcrn>5Ti+PpH*@O%w7#VP%-qwLMPH;ko$E@Rg6o10LBL)gAI)I-|5 zbl{mPqCJsP4Tj2ji zv1!xL7p7NMQ$gI9y_uvp6G`Q(nx`r6=x4$yAiv)=bUD9R;1G`VQK%v$o(2h2t*0At z=Ib+b`;Dogo`MVgrIT62=`vQ=vQ=Z8@l~Q!w^d5MM6}dMdRwpu zJy^YW`)=h_ss_yS=OOvTaYru&IzH0=KXjm@406zOLe!?5JSl8mWcqN3TnJmXg|oJS+B^=*)TU|8K5f6| zdig=-WT2$_=^CK*OPxPys| zcnXwWS?1ja8*xs~X^IGQUD!$74Xq5lj;?RZPFvwDT-@5!4xZ&*uPNf#uowl9A2^ww zZ-7-H&#g4|vuSfVQ>%B5Uw9@lKChkZt-9C1e^};CtOXN1Io^Pw2b|h(VY2dA=;KcK zUfn*n-;+;n1|}S7+37qu=OQsob@4Xg2ktwWgURxVaD!l91=nT?1?*$tGTGqy(H-J2i{E)Rf0ktA2xAO9H{5x1>->fNHV+Dn<5r zm+N>B1jB5B`&k$Ap1V%XrP} zhjcp~WXI&ik!rD&$^0cK8HR*R7@6+E%ls=ywlTbXLaKnp(^{v)j;?rMet=)4kFaS{ zl*79gBzoSUjX)VO%B%~?E?2`3n8}Ptzk@BPg>bS%oO3jO#6w>cLt167UR6PV@xBOg z?vMxRQ2ETX`*aLrJ(&c2`pEPuLXMTBZhm6VmvWvxhT%^d%=RtQJp|SF6ny+495u#W*{Z9G=hlR2%|JKVl zX;t$pNHN8DF2H0qY>k%lDmVfgXM%!I|Mp*ogs6eRVS*X83A@QQK~-r}5-_h8oz)3u zP^hy*@vKvMwPcz!zTJJ5_k=S2mcP++8`T~@8AzMGeX@FWf^6kd^ufm_(XLrad42yc zkNXyV8X_5ggDhvI1^*I4V)dCGn|mjHGulZ%o#I+TQJ`If2J-j${b9p?xK|jKNB99y zjBeU`gF3t?>4L(#;(>d`Pis1F)=vrH8aaAW3+z&F{^^n)Dk1u47IO>e5%ElVVguxw zx<0MRxkn|65b$Sr+e9Hgg_h+y5ZMIg-JEf@-TKE|F*p$^2}Dh!=dJpQuLm?nM`W(1)sCzDoZ!l{?q$ zA)R)@O?(WR2!3A;Zli#5IH2qT8n-+VW^li|(T`&K8lg|2 zfrCA&jixXR-gfFoT;#fCFqd7fUC!<+!i_p}MFL+4E?{k_^p zT!U*;)`#ngRZk3An@^i9z0bEGqY8N&tY(*EnC`$)HEy)fB3>$OIBCcgN=9ZbzLb>Rzn94QfIrp zW9oQ{K3=E?QkC$3d-$-bp0O#RT$yHR0xGOk(^d_7_GGGa>QN~h5QYeQg=S>)ce^I3 zMn=$NoKBTae7X?X`skQ3{RL(wX9{XuYgwhDQa?VY+-#iZ$;v8feW*30b@$km0_}NiDCwSX`st+paS#4Tev~ z-4%~UyV@`s8E>6d{}^8{ODvn60i^B5K#tJqF7FL5IcuO9v^4*<#aBX15Jyfzhc3zO zEJ402vDYjwehcq>9-@9qiZwDDvosrX`aAKp%=$_t1rTu?(^*6pc>qwg-sXyu|@a`Z(v zmE2q%s;Pye%54fG83|pF-4ixgznYV4(ZiD@CFG?s_`;EL+QsCPrz!rEFD<5^>N%;B zY0y`*c^KQm5|e-jezx&muk!*=7wJ8iCm2Y3gos{{*ue-K*eOn=0wBebq~!(OelMV> zaljhUX92c{?BI$-ocW#JOA|s<1Y>Ng4Rt1}&y$BHewO~=b%4tt!ugGya8N0hqDS5% zm=l=cy*|g7frk41BJu5h^RYu|w%I3G)j}0~-_0n`#W8$K5MTZX7p|Il?h_^7SX+`W z7xn2i!kkeIfb{I0;};O8gs-dC^S^*#cd7h^p7p^!vIj>`N*7v6mC8ufR5pQD8{ARb zYA55R&ktqyRx}()UB0Gl-c6JzlI+b!c1K!@m^%_2xhMN2{#Y=apic|P7HJx;N+4uB zug6#`BQm3}wMW#ofwZABF#eq`;0X0G3KWW=psjS4GKcFAY(wrzG%c*xA@9j51gkL7 zQ>Q(m_S-J0s6(y>*(teTp3tiU%3a(erAKPh+l@govB*!MdP9+>Er2izXG1!9`3skO z{p5n4v{#Gv;`m%_glzv>r960FI?jxNVkBxSC{c%MTeiU3&nU28%V$zr7rL{km>Dg= z3XluGo~cFE#%wigE2NFD(DDpbnPE%OY)9FvwA7t%tmS^!89Nx89Np>iGEJM*536kK z7Zu6k7kR=Np|;0vjQXt-*W*klR8hZZh~sNCr+ESrcg}z6SV#pB03y9E#SdDwo8RsZ z{ZH?}A^%C!La}NM^`ui|mi{bjb@`8{QyQlqyxAnPP>sv%k?SI-rxI(P7J8B8VV}Ia z;>rz9pN`U$Y*)0AdmB^7q1J}LD)JCUjxhiZuLh#$Ns?t2?aE9wSa+U>-;IZUU$0`k zJ8fs8M}6L}5ous%VO?*cc&9(V>p@^`#j3(f95N%x;&$6`RvEXA;I055SIXyV|VTPyyZP}K3h+P6uiJ74rQpWaFJl=@Bv%hvEk z=GiL0an9={S{$F)h9|yq3rB3eU09JelaNyU^6aIJ;QSg zr|>KtN!s)}V;cJ3TFdV!(3n+`b+GDP^I*8F?}EqgHw3m9t8pfSd2Y`YTl%kL!g>3J z{g%%Cf3N@B_rV}x5xw_dlkJw#lAZ?`Ev#>X;mEEx5iG%fkCH6NuxEA`SGITW7K{nl zIu6IU`4Jr@uDk6NmEUkHMUWt2`kcQ_x4j9$x7BOIfVcoq`U58wk zTp(*gq#D))*IY*;&PV8}EPO(08h>noP!_`ic)`_`5r?b*`=a{=PLck3!EXW*JS4~% zQ-S_$9MY`QSqcbel4r+LH7t^{*z-rzn56%{RMY=Dr!78Qx{7o$k#+;nm;V4B&t|tE zsbBk=-t@lHxh>=t#;?B`i7>{Dev4aO&CO&%3tud1ygbO?CMqpE`i`tNP001LQb8-gLy-7fD`Apwq$)}*Nbtu3{`tgy|5vig3$fGqyVa=*m&lE@} zoh$9>@-xkZfHka-u@T{!%CdgIpck-?K?{MFL3Sq#YsrQ7;d@>=4YQ4~Sfgm9@084N zot94Z)r=cYN6k|fr{nqQ!@^{a%fZNnwc3``t0uJ3l6TAGnvvaA*vVc)OC0Cu?>9zi z8jw^jP1;5~!t-8b8z0h;T`gsGkAai%g{Ia~dw&~=nT*ZF1*h+%{rydLgN?R1#mL5a zt-JSKIa?y%A6@AwZt}8wet3R99A>mG>>f9o=rcF#$MURL0zepRw!bKBKD`lksd}=$ zBo|cU{LfEw#$m)*Z1`kvA>?D0#M~Ov{o3-tag9ULcCR|Kf_(cslbc!9?z4YplLAe- zUdc`xH&^woFgnM%VbW7rOpzk+{XerKH3;z{YqC-0W=(697DPvoDXiGEf7M#Vxu%Yo z{y!hBraB8lF)pb}qJ{$fx|4mT$vSPwO*vPoxo31VjrjAJR`GK|pL5Fv=appR8l7g8 zfbEOk=&0`wY69EQZyFw_TU{(kF;(1b6klF1Ow*)tmTX)s<0~3hR?XJ*KSPZ!3a=O7 zIu6&Td54kY2AsCmkjoEY5ghw^B?Uu$u_CmzQXhRBU(VSDT|I9Qp`37PzC4YOawy&e zOJ)CznN)&0mz6W-A zd5ieq^+*nqxA^10Acey)Q*2J<%nWcKS04G1oBX1sa9|9<^TU@fnWt7?>cJClZu{8eoY%Dfy2Z#raQElp zvTQ8(r|0Hm>Zr{8PJzYdSEvI9WtDOxp-D>G5oD^TEF zm^xRJC+7)yl$+=iK(BMNdD@-429lxKr`Y7Icg`M}+w=LfuLb0j zP!0J%X)n^Aa)u=D79;-4Cr;ATM18NH?u!IJ7!}Z@Y;^nub3nwCl^exZ~%5A zmJkL49>Z<0DN{#h_DqV@MP_Dp{D4itQcnH)mxZ}GpqbeG z{C_sSV{1$LI6ldm&Bc9O?LR`F0={eC-cxtDm+Ba0Hvi9#+IndsRNH#b7l+OEsmT|G3!O5( zFL#c1ZMF2Fm!Plbgflc^)_`;K=e@jpv@uZaKj?4AeVn4`H8`bk{>&2T|pp~`vq9rNN zu$ruC`x>hp?D4k+RZE1Yh^YTd-f8E4rwx_DvHiXIM=UIKjtQsoyct^k>S}dAD}PIM z^Wb$`Dzf$l0xTObZocqEX{)q+vDd(_b5ixRzCdh4z}-7r>yuAwlz2VKEF~`v&4YK9 z&KjuHgnR8vdGOHc(-D%@==(b4lf=ffKwrXpXb1L;?2O#ohfwnP1uJ75pVfCK+|XvJ ze6;-pdAlEW$dR*>C_4*A*wOxhB-l~gsD}S+1P1&0poi{Y27~C!Aa55J74N#1!!B|(zAYnhEOlQgX^6HuN~Ix{Dk zk0&A0GSJgrgzpzi&6s7THtO%n>S|HR)6!1e!GnVjA1H4(7j1dG?(cYO)HikpJk{ke zym2Zm!oL~x?|J%lUHzVX(5n5Jw{Jid7tk*vl931;X+t%CcDp@pB`ADmr?~JCW5ysP zLmY*h@LnF&-4!XLdMfjgndVPc^}PYLC09unlKbkyo;g=A9jn_XVEQPSZi!gX^nG9= z6D!lc(!qsE@aJzCTW<%?X6- zXo0dOJ`2Bvjc4`wMI}=FKWXxq>U{0R;LhqltHb-JzzV2Puu|XkXB1_KVt|h%JP7jq zTJD-A%fI~1jDyqg`_FrYSbxS<-G=Ocipn@ub2hwPJm6b(r3}B_*A8876&JFT9OvU+ zfxgtVk?DIFqMBOsa!>Mn`Tyjf+QPY}u4@tNfk}4fgZO)w$eY#J=t$tlwd;=sZ*~8_ zznP4GX<`4KdBoJBagmR_eI*UbEGJBuC!LbZqR)Ipc`Hb4@VF}exKQj6oiaBJvUHKg zE^Jh!jR3HXoV`oai7SHr7Yl6~5Iq}*tKon(?oFz`eYSJJT$uztbAAe6jf5hE=!E;YuFi@SnI@t=Nge-8WEBNCfrQkYO z#o&){-#AISQZ_u2yp`46?ek-NvGo@@pg(p@b|-sOvFnH|+~<{i$|wsB5FhswcA6ss zJ#pmX+OzW(9p>GaXa@@b!FaF%nI=09PU!ft@PF#OFX=lVi3|!HR>nEnh1^L^AWnW6 z)(a*u1mV2u479>){CPzhbUS^)-j+O_uczg39y)#*q`L!5)>|P@w-|uly}R?K{M&}t zB~C>mz*#dT+qEWF!0)8r!F$_v;9TN3O-C1!beol0{PrVwTVYao~F6 zf^Ca*8{A;Kv7K`n-UmV)NUL5#1?P{!|8`wMKy1cw)*4J|b_3AXmr$4Oy zd7u4olGc6_&X3`&H~2Zv>$c(2!Z9u#s@NJV<0DwzCfx(CaZ5kMKYmxJHdw35N|EGP zn9-}mT{MiV{gvUeHE5?brUmu-=d)0@_ZKSz9{tfe(x~>PLs*9!45hyP&G@G63Ddfg zWU2m)rPb26^~0Y9UjNLQQ3t7-r{qI69XAIj z^K(47z|$0~uqj$U@e=wPtSjHem!-=*>5bmm&_S#+O`U{aUl~Iqv}UNAkRNU?f2=^w%g@OP!4KSj z0U`jl27UN@RRCV+tbqDiH;llEzIVsT|n_2XBPWu&NpGA7XrrdUhWgQSJ&?`<4ab*?K$`Sz^!51GpDH}nv=XQMF}V4VF`6XWXzzR|p+I2{ zcTB~+YJ(h26zwf0o&$B^4yV_3Y_J71$wGjdrOXQ(6GjM-bo=0&wuv_$$*}hvT^=3d zi$(24naRdCN1b9(X8bb};kA4QzH)y(U^I|MAMz<5n!i_~tIKCB9s^6zF2VNsixhQ; z`i$BF@wRVaR$kKl#qvp0rYkI9|9YctIUD-gCd_Bcu8)D>5$W`ys(KzxS8q4@4OEjn z{-R$u3P9pO0e2=?ne`~^ao8@c_>0gDCxycwaWE%p)d!BrjC!V;=;#l_ z;>jO16mUnHFq9eeP0EBEDRQjJWjG(I%&$ zh0L>b$)4Vx!;6l|^=gv#_aFaP}$B z>Et<`XY)ye`Q7;nJgD+^klOL9o#lns$0W8v;qas4DLnAqIav?H4p z?weYvJ=(u95TP}6tpD3HU`usSU)}w2qB^9474xX;&vWjN%$h3Vt(gnvmLo<{yfs1# z3`sZEBDe0DS)g8KZ_2E?IofP~_Ar+qEaZh<(Nb8sM2IwHm1(h(pz)I_W;Zuip1ojk z(A0OW=fR&$OhelCAo%KZ4kb2tSoGL<$Bp&j@h;}bmm75iYaO=JAE|Z_*fQZx#s$vT qyt)-H-P~--HWmSI?%#&~T^!!n1a%TpQ8C~*I4@LnRH~I;Mf@*TXs9p% literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-conv/index.html b/apps/website/public/widgets/nn-conv/index.html new file mode 100644 index 0000000000..b8e5e1157c --- /dev/null +++ b/apps/website/public/widgets/nn-conv/index.html @@ -0,0 +1,47 @@ + + + + + + +Patches of a picture: a 2 x 2 window, averaged · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Patches of a picture: a 2 x 2 window, averaged

+

Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/avgpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 10 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-conv/logic.js b/apps/website/public/widgets/nn-conv/logic.js new file mode 100644 index 0000000000..9eceaf812d --- /dev/null +++ b/apps/website/public/widgets/nn-conv/logic.js @@ -0,0 +1,44 @@ +// Generated by scripts/t27-logic.mjs from avgpool2d_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: de15759fd183094a4dfdff2ea074dfaa79607bc31c789347eed1df151639e9fb +// Imported by scripts/widget-logic.mjs for public/widgets/nn-conv/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABGgVgAAF/YAF/AX1gAAF9YAN/f38Bf2ABfwF/AwgHAAECAwQBBAQFAXABAQEFAwEAEQYJAX8BQYCAwAALB3gHBm1lbW9yeQIAD3QyN192YWxpZF9pbnB1dAAAEHQyN19iYWNrd2FyZDRfYXQAAQ90MjdfcG9vbDJfdmFsdWUAAg50MjdfcG9vbF9jb3VudAAEDHQyN19wb29sNF9hdAAFFHQyN19jYWxjX291dHB1dF9zaXplAAYK0gYHBABBAgucAgMHfwF9AX8jgICAgABBwABrIgEkgICAgAACQEHAAEUNACABQYCAwIAAQcAA/AoAAAtBACECA30CQCACQcAARw0AQQAhAyABIQQDQAJAAkAgA0ECRg0AIANBA3RBwIDAgABqIQVBACEGIAQhBwNAIAZBAkYNAiAFIAZBAnRqKgIAQwAAgD6UIQhBACECA0ACQCACQSBHDQAgB0EIaiEHIAZBAWohBgwCCyAHIAJqIgkgCCAJKgIAkjgCACAJQQRqIgkgCCAJKgIAkjgCACACQRBqIQIMAAsLCyABIABBAnRqKgIAIQggAUHAAGokgICAgAAgCA8LIARBIGohBCADQQFqIQMMAAsLIAEgAmpBADYCACACQQRqIQIMAAsLSgIBfwF9I4CAgIAAQRBrIgAkgICAgAAgAEGAgID8ezYCDEHQgMCAAEECIABBDGoQg4CAgAAaIAAqAgwhASAAQRBqJICAgIAAIAEL0wEDB38BfQF/QQAhA0EAIAFBfmpBAXZBAWogAUECSRshBCABQQJ0IQUgAUEDdCEGA38CQAJAIAMgBEYNACACIAMgBGxBAnRqIQdBACEIIAAhCQNAIAggBEYNAkMAAAAAIQpBAiELIAkhAQNAAkAgCw0AIAcgCEECdGogCkMAAIA+lDgCACAJQQhqIQkgCEEBaiEIDAILIAogASoCAJIgAUEEaioCAJIhCiABIAVqIQEgC0F/aiELDAALCwsgBCAEbA8LIAAgBmohACADQQFqIQMMAAsLWwEBfyOAgICAAEEQayIBJICAgIAAAkACQCAAQQJHDQBB0IDAgABBAiABQQxqEIOAgIAAIQAMAQtB4IDAgABBASABQQxqEIOAgIAAIQALIAFBEGokgICAgAAgAAuaAQIDfwF9I4CAgIAAQdAAayIBJICAgIAAQQAhAgJAQcAARQ0AIAFBAEHAAPwLAAsgASEDAkADQCACQRBGDQEgAyACszgCACADQQRqIQMgAkEBaiECDAALCyABQcgAakIANwMAIAFCADcDQCABQQQgAUHAAGoQg4CAgAAaIAFBwABqIABBAnRqKgIAIQQgAUHQAGokgICAgAAgBAsVAEEAIABBfmpBAXZBAWogAEECSRsLC20BAEGAgMAAC2QAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAACAQAAAAEEAAEBBAACAQQAAgD8AAABAAABAQAAAgEAAAKBA"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function calcOutputSize(heightIn) { + return W.t27_calc_output_size(int(heightIn, 0, 4294967295, "calc_output_size.height_in")) >>> 0; +} +function pool4At(index) { + return W.t27_pool4_at(int(index, 0, 4294967295, "pool4_at.index")); +} +function poolCount(side) { + return W.t27_pool_count(int(side, 0, 4294967295, "pool_count.side")) >>> 0; +} +function pool2Value() { + return W.t27_pool2_value(); +} +function backward4At(index) { + return W.t27_backward4_at(int(index, 0, 4294967295, "backward4_at.index")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward"]); +export { + __NOT_LOWERED__, + backward4At, + calcOutputSize, + pool2Value, + pool4At, + poolCount, + validInput +}; diff --git a/apps/website/public/widgets/nn-conv/logic.t27 b/apps/website/public/widgets/nn-conv/logic.t27 new file mode 100644 index 0000000000..d542f5430a --- /dev/null +++ b/apps/website/public/widgets/nn-conv/logic.t27 @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// 2D average pooling formula | φ² + 1/φ² = 3 | TRINITY + +// #8980: the kernel and stride were string constants typed `[]u32`, forward only +// asserted that its input was non-empty, and the tests asserted `true` or +// `result != undefined`. Average pooling now runs over one square H x H channel +// with the default 2 x 2 window and stride 2 and no padding, and each test checks +// numbers. + +module Avgpool2d; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_KERNEL : u32 = 2; + const DEFAULT_STRIDE : u32 = 2; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const PoolConfig = struct { + kernel_size : []u32, + stride : []u32, + padding : []u32, + }; + + pub const PoolShape = struct { + batch : u32, + channels : u32, + height_in : u32, + width_in : u32, + height_out : u32, + width_out : u32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // Output side for an input side n: (n - k) / stride + 1, and 0 when no window fits + fn calc_output_size(height_in: u32) -> u32 { + if (height_in < DEFAULT_KERNEL) { + return 0; + } + return (height_in - DEFAULT_KERNEL) / DEFAULT_STRIDE + 1; + } + + // output[oy][ox] = mean of the k x k window at (oy * stride, ox * stride) of a side x side + // input; returns the number of outputs written + fn forward(input: []const f32, side: u32, output: []f32) -> u32 { + const n = calc_output_size(side); + const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL)); + var oy : u32 = 0; + while (oy < n) { + var ox : u32 = 0; + while (ox < n) { + var sum : f32 = 0.0; + var ky : u32 = 0; + while (ky < DEFAULT_KERNEL) { + var kx : u32 = 0; + while (kx < DEFAULT_KERNEL) { + sum = sum + input[(oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx]; + kx = kx + 1; + } + ky = ky + 1; + } + output[oy * n + ox] = sum / area; + ox = ox + 1; + } + oy = oy + 1; + } + return n * n; + } + + // backward: each window's gradient is shared equally by its k * k inputs + fn backward(grad_output: []const f32, side: u32, grad_input: []f32) -> void { + const n = calc_output_size(side); + const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL)); + var i : usize = 0; + while (i < grad_input.len) { + grad_input[i] = 0.0; + i = i + 1; + } + var oy : u32 = 0; + while (oy < n) { + var ox : u32 = 0; + while (ox < n) { + var ky : u32 = 0; + while (ky < DEFAULT_KERNEL) { + var kx : u32 = 0; + while (kx < DEFAULT_KERNEL) { + const idx = (oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx; + grad_input[idx] = grad_input[idx] + grad_output[oy * n + ox] / area; + kx = kx + 1; + } + ky = ky + 1; + } + ox = ox + 1; + } + oy = oy + 1; + } + } + + // 4 x 4 input 0..15, row-major: windows average to 2.5, 4.5, 10.5, 12.5 + fn pool4_at(index: usize) -> f32 { + var input : [16]f32 = [0.0] ** 16; + var i : usize = 0; + while (i < 16) { + input[i] = @as(f32, @floatFromInt(i)); + i = i + 1; + } + var output : [4]f32 = [0.0] ** 4; + _ = forward(&input, 4, &output); + return output[index]; + } + + // forward over a 2 x 2 input (1, 2, 3, 4) or a 1 x 1 input (5); returns the outputs written + fn pool_count(side: u32) -> u32 { + const four : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + const one : [1]f32 = [5.0]; + var output : [1]f32 = [-1.0]; + if (side == 2) { + return forward(&four, 2, &output); + } + return forward(&one, 1, &output); + } + + fn pool2_value() -> f32 { + const four : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var output : [1]f32 = [-1.0]; + _ = forward(&four, 2, &output); + return output[0]; + } + + fn backward4_at(index: usize) -> f32 { + const grad_output : [4]f32 = [4.0, 8.0, 12.0, 16.0]; + var grad_input : [16]f32 = [9.0] ** 16; + backward(&grad_output, 4, &grad_input); + return grad_input[index]; + } + + fn valid_input() -> u32 { + return calc_output_size(4); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test calc_output_size_basic_case + given result = calc_output_size(4) + then result == 2 + + test calc_output_size_valid_input + given input = 10 + when result = calc_output_size(input) + then result == 5 + + // A 1 x 1 input holds no 2 x 2 window + test calc_output_size_small_input + given input = 1 + when result = calc_output_size(input) + then result == 0 and calc_output_size(2) == 1 + + test calc_output_size_large_input + given input = 1000 + when result = calc_output_size(input) + then result == 500 and calc_output_size(1001) == 500 + + test forward_basic_case + given first = pool4_at(0) + when last = pool4_at(3) + then first == 2.5 and pool4_at(1) == 4.5 and pool4_at(2) == 10.5 and last == 12.5 + + // A 2 x 2 input is one window: the mean of 1, 2, 3, 4 + test forward_non_empty_input + given count = pool_count(2) + when value = pool2_value() + then count == 1 and value == 2.5 + + test forward_single_element + given count = pool_count(1) + then count == 0 + + // Each of a window's 4 inputs gets a quarter of its gradient + test backward_spreads_the_gradient + given corner = backward4_at(0) + when last = backward4_at(15) + then corner == 1.0 and backward4_at(5) == 1.0 and backward4_at(2) == 2.0 and last == 4.0 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // kernel_size[i] >= 1 + invariant avgpool2d_constraint_0 + assert DEFAULT_KERNEL >= 1 + + // stride[i] >= 1 + invariant avgpool2d_constraint_1 + assert DEFAULT_STRIDE >= 1 + + // stride[i] <= kernel_size[i]: windows tile the input without gaps + invariant avgpool2d_constraint_2 + assert DEFAULT_STRIDE <= DEFAULT_KERNEL + + // name: avgpool_formula -- (n - k) / s + 1 + invariant avgpool2d_constraint_3 + assert valid_input() == 2 + + // "Zeiler & Fergus (2014) - Visualizing and Understanding Convolutional Networks": pooling halves each side + invariant avgpool2d_constraint_4 + assert calc_output_size(8) == 4 + + // "He et al. (2016) - Deep Residual Learning for Image Recognition": a 7 x 7 map pools to 3 x 3 + invariant avgpool2d_constraint_5 + assert calc_output_size(7) == 3 diff --git a/apps/website/public/widgets/nn-conv/nn-conv.t27 b/apps/website/public/widgets/nn-conv/nn-conv.t27 new file mode 100644 index 0000000000..df845ff1df --- /dev/null +++ b/apps/website/public/widgets/nn-conv/nn-conv.t27 @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-conv.t27 -- a window over a picture: 2 x 2 average pooling +; Source of truth for public/widgets/nn-conv/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-conv/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/avgpool2d_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 10 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader taps a window, on the image or on the output, and toggles the gradient +; view. Outputs are pool4_at(i), the output side calc_output_size(4) and the gradient +; backward4_at(i) for the spec's output gradients (4, 8, 12, 16). + +; WHAT IT DOES NOT CLAIM: this is AVERAGE pooling with a fixed 2 x 2 window, not a convolution with +; a learned kernel: the sliding conv2d spec is gHashTag/t27#10612, not merged when this page was +; made. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_conv; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-conv"; +pub const TITLE : str = "Patches of a picture: a 2 x 2 window, averaged"; +pub const DESCRIPTION : str = "Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch."; +pub const IMAGE_ALT : str = "Window card: a 4 x 4 image holding 0 to 15, with the 2 x 2 patch 2, 3, 6, 7 outlined and the rest dimmed; beside it the 2 x 2 output 2.50, 4.50, 10.50, 12.50 with 4.50 outlined. Tiles read window 2 / 4, average 4.50, output 2 x 2 and gradient share 2.00."; +pub const HOOK : str = "Pictures are read in patches. Here a 2 x 2 window steps by 2 over a 4 x 4 image and averages: 2.5, 4.5, 10.5, 12.5. A learned kernel comes next."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/avgpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 10 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SIDE : u8 = 4; +pub const K_KERNEL : u8 = 2; +pub const K_DEFAULT_KERNEL : u8 = 2; +pub const K_DEFAULT_STRIDE : u8 = 2; +pub const K_WIN_ROW : [4]u8 = [0, 0, 2, 2]; +pub const K_WIN_COL : [4]u8 = [0, 2, 0, 2]; +pub const K_PRESET_WIN : [3]u8 = [1, 0, 3]; +pub const K_PRESET_GRAD : [3]u8 = [0, 0, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["Window 2", "Window 1", "The gradient of window 4"]; +pub const SAY_ASK : str = "How does a network look at a picture: all at once, or in patches?"; +pub const SAY_SHOW_GRAD : str = "show the gradient"; +pub const SAY_IN_LABEL : str = "The 4 x 4 input: tap a patch"; +pub const SAY_GRAD_LABEL : str = "The gradient each input receives"; +pub const SAY_OUT_LABEL : str = "The 2 x 2 output: one number per patch"; +pub const SAY_WINDOW : str = "window"; +pub const SAY_AVERAGE : str = "its average"; +pub const SAY_OUT_SIDE : str = "output"; +pub const SAY_GRAD_SHARE : str = "gradient per input"; +pub const SAY_NOTE : str = "Average pooling, not yet a convolution: every window weighs its four cells equally. A convolution would weigh them with a learned 2 x 2 kernel and usually step by 1; that spec (t27#10612) is still open."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/avgpool2d_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_windows_tile_the_image { + assert K_SIDE == 4; + assert K_KERNEL == 2; + assert K_WIN_ROW[3] + K_KERNEL == K_SIDE; + assert K_WIN_COL[1] + K_KERNEL == K_SIDE; +} + +test the_window_steps_by_its_own_size { + assert K_DEFAULT_KERNEL == K_DEFAULT_STRIDE; + assert K_WIN_COL[1] == K_DEFAULT_STRIDE; + assert K_PRESET_WIN[2] == 3; +} diff --git a/apps/website/public/widgets/nn-conv/tool.js b/apps/website/public/widgets/nn-conv/tool.js new file mode 100644 index 0000000000..c4a3e6dabb --- /dev/null +++ b/apps/website/public/widgets/nn-conv/tool.js @@ -0,0 +1,37 @@ +// nn-conv/tool.js -- lesson 10 of neural-networks: how a network looks at a picture in patches. The +// window slides over a 4 x 4 image two cells at a time and each output is the AVERAGE of its 2 x 2 +// patch: average pooling, not a learned kernel (a sliding conv2d spec is gHashTag/t27#10612, not +// merged). Every output is pool4_at and every gradient backward4_at of gHashTag/t27 +// specs/ml/layers/avgpool2d_layer.t27, compiled to wasm (./logic.js). The input is the spec's own, +// cell i holding i. Words are SAY_ and numbers K_ constants of specs/widgets/nn-conv.t27. +import { backward4At, calcOutputSize, pool4At } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, root, say, source, tiles } from '../nn-kit.js' + +const SIDE = K('K_SIDE', 4), KER = K('K_KERNEL', 2) +const R0 = K('K_WIN_ROW', []), C0 = K('K_WIN_COL', []) +const ctl = controls([ + { key: 'win', kind: 'hidden', min: 0, max: 3 }, + { key: 'grad', label: say('SAY_SHOW_GRAD'), kind: 'toggle' }, +], { names: W.SAY_PRESET_NAMES, values: { win: K('K_PRESET_WIN', []), grad: K('K_PRESET_GRAD', []) } }, draw) + +const img = canvas('nn-heat', say('SAY_IN_LABEL')) +const out = canvas('nn-heat', say('SAY_OUT_LABEL')) +const stat = el('div') +const inLabel = el('p', { class: 'dk-label' }) +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('div', { class: 'nn-two' }, el('div', {}, inLabel, img), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +const inWin = (w, r, c) => r >= R0[w] && r < R0[w] + KER && c >= C0[w] && c < C0[w] + KER +function draw(s) { + const n = calcOutputSize(SIDE) + inLabel.textContent = s.grad ? say('SAY_GRAD_LABEL') : say('SAY_IN_LABEL') + heat(img, { rows: SIDE, cols: SIDE, value: (r, c) => (s.grad ? backward4At(r * SIDE + c) : r * SIDE + c), lo: 0, hi: s.grad ? 4 : 15, w: 400, cell: 92, fmt: (v) => fmt(v, s.grad ? 2 : 0), mark: (r, c) => (inWin(s.win, r, c) ? 'on' : 'dim'), onTap: (r, c) => ctl.set('win', [0, 1, 2, 3].find((w) => inWin(w, r, c))) }) + heat(out, { rows: n, cols: n, value: (r, c) => pool4At(r * n + c), lo: 0, hi: 15, w: 400, cell: 150, fmt: (v) => fmt(v, 2), mark: (r, c) => (r * n + c === s.win ? 'on' : 'dim'), onTap: (r, c) => ctl.set('win', r * n + c) }) + stat.replaceChildren(tiles([ + { label: say('SAY_WINDOW'), value: `${s.win + 1} / ${n * n}`, tone: 1 }, + { label: say('SAY_AVERAGE'), value: fmt(pool4At(s.win), 2), tone: 0 }, + { label: say('SAY_OUT_SIDE'), value: `${n} x ${n}`, tone: 2 }, + { label: say('SAY_GRAD_SHARE'), value: fmt(backward4At(R0[s.win] * SIDE + C0[s.win]), 2), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-dropout/card.png b/apps/website/public/widgets/nn-dropout/card.png new file mode 100644 index 0000000000000000000000000000000000000000..a92eadc4eb05f37d46ef7adf4494e33912271ad2 GIT binary patch literal 42927 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 + + + + + +Dropout: training a network with neurons switched off · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Dropout: training a network with neurons switched off

+

Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/dropout_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 9 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-dropout/logic.js b/apps/website/public/widgets/nn-dropout/logic.js new file mode 100644 index 0000000000..53f88bc938 --- /dev/null +++ b/apps/website/public/widgets/nn-dropout/logic.js @@ -0,0 +1,28 @@ +// Generated by scripts/t27-logic.mjs from dropout_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 1d8495587051334995edcb6e2d6a2dffb81528aa1a6a78f86d94bc88ccadb3ec +// Imported by scripts/widget-logic.mjs for public/widgets/nn-dropout/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABDgJgAn9/AX1gA39/fwF9AwMCAAEEBQFwAQEBBQMBABEGCQF/AUGAgMAACwctAwZtZW1vcnkCAA90MjdfYmFja3dhcmRfYXQAAA50MjdfZm9yd2FyZF9hdAABCscDAqYBAwF/AX0BfyOAgICAAEEgayICJICAgIAAIAJBEGpBACkCiIDAgAA3AwAgAkEAKQKAgMCAADcDCEMAAABAQwAAgD8gAEEBcRshAyACQQhqIQRBfCEAAkADQCAARQ0BIAQgA0MAAAAAIABBlIDAgABqLQAAGzgCACAAQQFqIQAgBEEEaiEEDAALCyACQQhqIAFBAnRqKgIAIQMgAkEgaiSAgICAACADC5wCAgR/AX0jgICAgABBIGsiAySAgICAACADQRBqQQApAoiAwIAANwMAIANBgYAENgAbIANBACkCgIDAgAA3AwggAUEBcSEEIANBG2ohBSAAQQFxIQBBACEBA30CQAJAAkACQCABQRBGDQACQCAARQ0AIANBCGogAWohBiAFLQAARQ0CIAFBlIDAgABqKgIAIQcCQCAERQ0AIAYgByAHkjgCAAwFCyAGIAc4AgAMBAsgAUGUgMCAAGoqAgAhByADQQhqIAFqIQYgBA0CIAYgB0MAAAA/lDgCAAwDCyADQQhqIAJBAnRqKgIAIQcgA0EgaiSAgICAACAHDwsgBkEANgIADAELIAYgBzgCAAsgBUEBaiEFIAFBBGohAQwACwsLLQEAQYCAwAALJAAAEEEAABBBAAAQQQAAEEEBAAEAAACAPwAAAEAAAEBAAACAQA=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forwardAt(training, scaled, index) { + return W.t27_forward_at(training ? 1 : 0, scaled ? 1 : 0, int(index, 0, 4294967295, "forward_at.index")); +} +function backwardAt(scaled, index) { + return W.t27_backward_at(scaled ? 1 : 0, int(index, 0, 4294967295, "backward_at.index")); +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "cfg"]); +export { + __NOT_LOWERED__, + backwardAt, + forwardAt +}; diff --git a/apps/website/public/widgets/nn-dropout/logic.t27 b/apps/website/public/widgets/nn-dropout/logic.t27 new file mode 100644 index 0000000000..4a12f21501 --- /dev/null +++ b/apps/website/public/widgets/nn-dropout/logic.t27 @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Prevent co-adaptation of neurons | φ² + 1/φ² = 3 | TRINITY + +// #8980: the tests called `allocf32` and `allocbool`, which no spec declares, and +// asserted `result != undefined`. Inference also scaled by (1 - p) even for +// inverted dropout, which already scaled by 1 / (1 - p) in training, so the +// expected activation shrank by (1 - p) between training and inference. Inference +// is now the identity when scale_during_training is set. + +module Dropout; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_DROP_RATE : f32 = 0.5; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const DropoutConfig = struct { + p : f32, + inplace : bool, + scale_during_training : bool, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) → void + fn forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) -> void { + const n = input.len; + var i : usize = 0; + while (i < n) { + if (training) { + if (mask[i]) { + // Neuron is kept, scale during training if configured + if (config.scale_during_training) { + output[i] = input[i] * (1.0 / (1.0 - config.p)); + } else { + output[i] = input[i]; + } + } else { + // Neuron is dropped + output[i] = 0.0; + } + } else { + if (config.scale_during_training) { + // Inverted dropout already scaled in training: inference is the identity + output[i] = input[i]; + } else { + // Classic dropout: scale by the keep probability at inference + output[i] = input[i] * (1.0 - config.p); + } + } + i = i + 1; + } + } + + // backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) → void + fn backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) -> void { + const n = grad_output.len; + var i : usize = 0; + while (i < n) { + if (mask[i]) { + // Gradient flows through kept neurons + if (config.scale_during_training) { + grad_input[i] = grad_output[i] * (1.0 / (1.0 - config.p)); + } else { + grad_input[i] = grad_output[i]; + } + } else { + // Gradient is zero for dropped neurons + grad_input[i] = 0.0; + } + i = i + 1; + } + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + fn cfg(scaled: bool) -> DropoutConfig { + return DropoutConfig{ .p = DEFAULT_DROP_RATE, .inplace = false, .scale_during_training = scaled }; + } + + // forward on input (1, 2, 3, 4) with mask (keep, drop, keep, drop) + fn forward_at(training: bool, scaled: bool, index: usize) -> f32 { + const input : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var output : [4]f32 = [9.0] ** 4; + var mask : [4]bool = [true, false, true, false]; + forward(&input, &output, &mask, training, cfg(scaled)); + return output[index]; + } + + fn backward_at(scaled: bool, index: usize) -> f32 { + const grad_output : [4]f32 = [1.0, 1.0, 1.0, 1.0]; + const mask : [4]bool = [true, false, true, false]; + var grad_input : [4]f32 = [9.0] ** 4; + backward(&grad_output, &mask, &grad_input, cfg(scaled)); + return grad_input[index]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // p = 0.5, inverted: kept units are doubled, dropped ones are 0 + test forward_basic_case + given kept = forward_at(true, true, 2) + when dropped = forward_at(true, true, 1) + then kept == 6.0 and dropped == 0.0 and forward_at(true, true, 0) == 2.0 + + // The expected activation is the same in training and inference + test forward_inference_keeps_the_expectation + given inverted = forward_at(false, true, 2) + when classic = forward_at(false, false, 2) + then inverted == 3.0 and classic == 1.5 and forward_at(true, false, 2) == 3.0 + + // The gradient flows only through kept units, with the same scale + test backward_basic_case + given kept = backward_at(true, 0) + when dropped = backward_at(true, 3) + then kept == 2.0 and dropped == 0.0 and backward_at(false, 2) == 1.0 + + invariant dropout_rate_is_a_probability + assert DEFAULT_DROP_RATE >= 0.0 and DEFAULT_DROP_RATE < 1.0 diff --git a/apps/website/public/widgets/nn-dropout/nn-dropout.t27 b/apps/website/public/widgets/nn-dropout/nn-dropout.t27 new file mode 100644 index 0000000000..dcee5951e5 --- /dev/null +++ b/apps/website/public/widgets/nn-dropout/nn-dropout.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-dropout.t27 -- dropout, inverted and classic: training with neurons switched off +; Source of truth for public/widgets/nn-dropout/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-dropout/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/dropout_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 9 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles training and inverted scaling. The rows are forward_at(false, +; true, i) (the identity, so the input), forward_at(training, scaled, i) and, while training, +; backward_at(scaled, i). + +; WHAT IT DOES NOT CLAIM: the mask is the spec's fixed one (keep, drop, keep, drop) with p 0.5, not +; a random draw; the point is the scaling, not the sampling. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_dropout; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-dropout"; +pub const TITLE : str = "Dropout: training a network with neurons switched off"; +pub const DESCRIPTION : str = "Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size."; +pub const IMAGE_ALT : str = "Dropout card, training with inverted dropout: three rows of four cells. Input 1, 2, 3, 4; output 2, 0, 6, 0 with units 1 and 3 dimmed; gradient 2, 0, 2, 0. Tiles read mode training, a kept unit 2.00, a dropped unit 0.00 and the kept gradient 2.00."; +pub const HOOK : str = "With p = 0.5, inverted dropout doubles the units it keeps while training (1, 2, 3, 4 becomes 2, 0, 6, 0) and leaves inference alone."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/dropout_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 9 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_UNITS : u8 = 4; +pub const K_PRESET_TRAIN : [4]u8 = [1, 1, 0, 0]; +pub const K_PRESET_SCALED : [4]u8 = [1, 0, 1, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Training, inverted", "Training, classic", "Inference, inverted", "Inference, classic"]; +pub const SAY_ASK : str = "Why would a network train with some of its neurons switched off?"; +pub const SAY_TRAINING : str = "training"; +pub const SAY_SCALED : str = "inverted (scale while training)"; +pub const SAY_GRID_LABEL : str = "Input, output and gradient of four units through dropout"; +pub const SAY_IN : str = "input"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "gradient"; +pub const SAY_UNIT : str = "unit"; +pub const SAY_MODE : str = "mode"; +pub const SAY_MODE_TRAIN : str = "training"; +pub const SAY_MODE_INFER : str = "inference"; +pub const SAY_KEPT_UNIT : str = "unit 0, kept"; +pub const SAY_DROPPED_UNIT : str = "unit 1, dropped"; +pub const SAY_GRAD_KEPT : str = "gradient, kept unit"; +pub const SAY_NOTE : str = "Dropping random units forces the rest not to lean on any one of them. Inverted dropout scales by 1 / (1 - p) while training so that inference is a plain pass; classic dropout scales by 1 - p at inference instead."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/dropout_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test four_units_four_modes { + assert K_UNITS == 4; + assert K_PRESET_TRAIN[0] == 1; + assert K_PRESET_TRAIN[3] == 0; +} + +test every_mode_is_offered { + assert K_PRESET_SCALED[0] != K_PRESET_SCALED[1]; + assert K_PRESET_SCALED[2] != K_PRESET_SCALED[3]; + assert K_START_PRESET == 0; +} diff --git a/apps/website/public/widgets/nn-dropout/tool.js b/apps/website/public/widgets/nn-dropout/tool.js new file mode 100644 index 0000000000..50c93745da --- /dev/null +++ b/apps/website/public/widgets/nn-dropout/tool.js @@ -0,0 +1,33 @@ +// nn-dropout/tool.js -- lesson 9 of neural-networks: why a network trains with neurons switched off. +// Dropout zeroes some units while training; inverted dropout scales the survivors up by 1 / (1 - p) +// so inference needs no change, classic dropout scales at inference instead. Every value is +// forward_at or backward_at of gHashTag/t27 specs/ml/layers/dropout_layer.t27, compiled to wasm +// (./logic.js): input (1, 2, 3, 4), p 0.5, the spec's mask keeps units 0 and 2. Words are SAY_ and +// numbers K_ constants of specs/widgets/nn-dropout.t27. +import { backwardAt, forwardAt } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, root, say, source, tiles, tone } from '../nn-kit.js' + +const N = K('K_UNITS', 4) +const ctl = controls([ + { key: 'train', label: say('SAY_TRAINING'), kind: 'toggle' }, + { key: 'scaled', label: say('SAY_SCALED'), kind: 'toggle' }, +], { names: W.SAY_PRESET_NAMES, values: { train: K('K_PRESET_TRAIN', []), scaled: K('K_PRESET_SCALED', []) } }, draw) + +const grid = canvas('nn-heat', say('SAY_GRID_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, grid, stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const train = !!s.train, scaled = !!s.scaled + // Inference with inverted dropout is the identity, so it shows the input itself. + const rows = [(i) => forwardAt(false, true, i), (i) => forwardAt(train, scaled, i), (i) => (train ? backwardAt(scaled, i) : 1)] + heat(grid, { rows: 3, cols: N, value: (r, c) => rows[r](c), color: (v) => tone(v, 8), rowLabels: [say('SAY_IN'), say('SAY_OUT'), say('SAY_GRAD')], labelWidth: 96, colLabels: [...Array(N)].map((_, i) => `${say('SAY_UNIT')} ${i}`), w: 640, cell: 120, fmt: (v) => fmt(v, 2), mark: (r, c) => (r > 0 && train && forwardAt(true, scaled, c) === 0 ? 'dim' : '') }) + stat.replaceChildren(tiles([ + { label: say('SAY_MODE'), value: train ? say('SAY_MODE_TRAIN') : say('SAY_MODE_INFER'), tone: train ? 1 : 2 }, + { label: say('SAY_KEPT_UNIT'), value: fmt(forwardAt(train, scaled, 0), 2), tone: 0 }, + { label: say('SAY_DROPPED_UNIT'), value: fmt(forwardAt(train, scaled, 1), 2), tone: 6 }, + { label: say('SAY_GRAD_KEPT'), value: fmt(backwardAt(scaled, 0), 2), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-elu/card.png b/apps/website/public/widgets/nn-elu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..0ab1ad1f0ea28ef02eb98b861699543c6df4dea7 GIT binary patch literal 47349 zcmcG0bx@qo)+P}Mgb;!R4T0cJ@ZcKUHF)sB-C^(m!9BR!;O-D0xO8 zZx0UzvwSjBSSb-A5zmC|x99(qJkk8${4EJ9et7d|KuActbk9Zq7LWvjg;D>OvWwoJ zKKWZZ!+rYUZ^17Uq(XLhBwZO@v^0qF7(_%_K=@BjNF4k!R5~i%^tgxjw=&18G6&q# z?Ozyk$G4}G)G1Xz$^zeP;j{fqJ_dHr$I(<)(H#HS*e7l}%$1Zl`!C%yGXUe-`@fUe zoOXk?0?KsrMgEZ~A(o@G4M}t~{d9k zjeI^I^X@J(h2L@iGlz+*A3q2Ph%8A~rc=-EB;&gRgOwXU^8fqg$5+PIWt^850>gkt zg=kyzEwX>X!6Cydfm)B!t#I@nJjU`b009w}*r=mvLM=?1UxWUccDAzRT-nXP&_qh* z`VSzcTIf_6t>i7OKIGJE_fR+zaG9@{?fJ;7kQ+^zK36BJIbw%Qd#Iv(*%tp?fTw)# zwM~qqZ5ZM?SLKG7pRgV+BjfBBeN4@C{Q65iA|FN9+uygxCwH_YqZkyBQC2`b!pOr~M zH}yp?MLSMG3-PvGYtwHQ+P%<(Flq~kN{&#}WbS({wgtJjxZHHko%o7@7bKB&P$i7O z;`_4uMyp!MWOk>l4ztJllO@p3-5zHhuku?W?SqvZm$c6ff!oJ?t~`1!jeDIpJlq3? z&ybM(P;zXa<_s8iS5DS=C39oe0Lw+gqR_!tmqQ(rx^45D(uo`T1gnzE1Tg*6fY>^Dj zS>32Sc97V>SY8}2)bWtf=5?TmSxru8H)?IM8Lo6I3%u(+?ee;OZv8r9Xfru9{dVNe zP*UmD<80qiQ1*RVk=N|WEfxZDfXx0jfv6VHQ-zv4!pN!zgWM$PQf6ed30hk~cp7)p z{yk@F16EOrP--f>+?=JE|#Xg8oqn*xR-iXd@9=mLqiPoOp8RGFtLEjR7%>!&}PNqCdwIT zy8^RN`h#ysPw`#R4bfxBH& zqJ2*uxpYa=!fq*!)lECHJhBuk!CoJ)>FU$0MT5k<@t;LIXQqq zN0i6yWT{&a<+6rP25HS^n&HtXso+qHF&fAmwws!DCB);|?+nBdujtvf-Ihce;v%C2 zj5^!ZzAz4S8?)UV2KzV7$HiY?z8_nA>yqIm2V0YlKg>F&2UQuObw+92qmj?2+){Z5 zr|4ZLmc1C!#dqXMHDI`L9B4^-R>ly?NWLUE%`Nn!hdTWA;-Th+o8=M`aK?J8pYLii zVktQg?}D|`-kkF{Qs!^7vv1ia-^Xi{Xyh+Z0QU?eC?mSH(BF_3jGDCIXs!|J-J-hdCXThjr zlJBhy$EIo74U$$CfDAs|&e7X|_ibp02JGN=@BO^y+ud2ABTNhyyWI%`p^S+R>)4co zUCs~5&7I^oinj|jz@DdOcFE|!Z+NRafgAtA{Kdz?zuZR1`1;o!5|7V#=Tw% z@$wrKA-qD-`|oo?n52D~(P`MV9_**3*-2D?qn{Qx+D%q&xe&0f&Unb1(yb^tZ5d@Swsk z$dmFO!$sHP5I4>VSyyUC{pHJQ0c}|^tJNIwh8{tIi!@)!+`0jDR-;RQpZmr`H{9qS z)z^4hO|R09511pPc|AX@F6WI4uWIRx#2FRZhB=%rRgHBfTc)M^T)AAgi*O$)YU|(a zkv<)m?(MIv#E`CdhY=w&99?NL1UM&76_Rs4uIx`bgRH)nj+2;c_m=EGTxf$PRrF8R zxW!!9jG;nYFWme6^L+Te7q|sJ3ygzN8Jem}n4;k;QWiJlAM9%7y$jn2y!>p6jo1OZ z%`Lnoatl(~!FggV_*NY~klmGG{{vK+=}mUhvl%vp5hzscVYE(`<;4RnxfU!|>sbp= zTC`)h_412Pse^Hf-nHJRw`uDAvs(tg@2)o*@mU_W2bjXfY}V!$e^$D% zir9z%e>aTdk1xF;=&|`uX}Q|C+|IP>&8k`mub^K*+6$(lXkuD@(*<^Q-UBdgNU+~E zbI>+d*>A->*$i>bzW;n`m##+{MY_lJQgQ|_CP6cx2h-~*@KZMv zwwtq?8y+O&`2Oywcl9`Yhs%Hn=jy1fH+)sUgDJ@OsmUIGV|%CjDMRkt?y+A%M! z`|LbNmkKkA_Bp=_+HU|9*{$q^445&tky#EF$}{92uf4AOFEeK6*H4qbj%*V?lTd(Y zcX|DcsLXRV1(frtHRt>ButcX<19a~41hjR;tiU-%#MLL*Bk`3<_gIT85w*|I)c7V3CGZn zb;p?q+a`&y#^!oynES;k&S$vTvnCSX)2VjlXaO;^6?X3TI(x=ggddOUAtD2T2(?zy zod1v@voTFMGua}k>7?~*?;~7>a=skC@IN%+tnQic+9!s;RFnGqVow? z-dxtG!DCfJeQjQflvhNoIP&}OGq0r{x8a48+0#>2&8V^m@9+wL)!1ex(tIkcA_^Q6 zwiZWTQMNvXbGNV&%bF*qQyVP5Ooo1?Tzj8vXPH;X4ab`mx;%5Pb|pPOEs~|VsPZZs zSzb)F8lpEz0@c{tS3{0j_lBxJ3f3odqLh(j=q#r3IVwhS1P~95(xe=UDkc0H?`w;c zz5ZGzGX+^IhMDUp8I+dC$r!Q0n^C)?n^msg>)n5AICWktl5a@4(%JYW**kW;98Zn# z1rE{@*+bOby*}1*a?84L;KM1tcVVTlNk8<)xbIcH&rh498I=>io?R6HtxhaQZGsk^ z0xwYdL45~PdCVHTZrNjDi?_h4iGBrae!DT4&!+?;#KIRJKh0qjqWF-7?yjF%bC><| zD|)5iv$m#VWk=Dzo|QSA49wV`;^3^YZA|OoChx0(m2krLZKhMFdnS8IL({`1y%8sqzhA1Y3# zQwWLNA;-U1Np3womfU%qD2VX`DVk0rU=E+8#lNmWB&YXbmAwat8s?e$Y%W_VlfZ{O zNz9{l)`{M{Jdf=d9xr376^in06txpTQ-MMjhw}U+sV{r=3vQs-Wp}KPWcPsE`U^oW zBM@hO>%^7Y&{gMD|bncPZ zTPoOYEQQD^bFEPuVAf(*-F|81H{i=(+stFjrIc*+-GdUFQ zGjn5_aLmY;?25U{-oA936%}F*)@p$tow>h01R;!$@{n`wVvU@#1A5OJFr^Ks;|Z)S zf6JL}A$DuAVVpF*X?$dMSX(9V^u>b{ zNLT#z(t znRUE2+K%ObqI!{fdysO^J7l&kFFCJwMMp)lk_%H}$AohUiK$M|Vv$?8pVXo&x;K`? zarlfdD`aR<@$&wMrDReT%le}zJZjDi^F=D0Ee|_?rmwnR3I8BlPV3r=j6(1O!)NR) zX@PfqH|{)k;WAantTW+{4OAcK^CYT^BVY`lfE zI&FpH7}qzpM_XP~)Lmo>TD7#MeBn(0%q3vv(`F_N1j?;#j~2ySU6?lYVN7UfVY`^X zKX+mX3JCrtWjoslMh)}m@9^PgZ+J!c=;2vUs-N_xjfu9TGAsPCI^JhINKcw9`AOii z1vKJGcuy3Hgd(oNs>_smh+OS5^0yg=+1P?^IC_q)utY-h8rJBS>y^ zOMjOl?Ha{(hn1*vA--k)y%AaWeS3cLc(S?JHYA0|@q-4D$5zN%YWqX|vCY z33?*8;uyc51O|^$#$4Y#M_z?RBrn?Y%rTmDg<5o-&d25VjM%h=L|){1LsNj5slxA_ zZlr#7zi;O+wEJR5VmzmLZ@AMC5%_^@etwR#k@>KteD06&~e;weQM6EFI}lT zE}!IWvJ!Ef#{6q%q3P9G#_oK-1Rg0Kc2bJu^@mmFwJeU3NOOb!v#-bN?*$(kJmB2# zB8&Xtb9M&oi_8=y8`;ti5I+pB%>v!=6}#NW!#&^%*IfzMUE%HcMb;PK>z>M9K*4_JHbblN{V1Wv(Tr)$DYpl@-y%<|TWc;y^5!Mvxr7hkW#`iI7OP0* zZb|kg3uWW4B?p#Q9~?KoX)(v;Ye$bbEH!$2{7j@QY3{EI!!cL9Jm-8>FvdX3+yU-e@NnX!*?q2_cmCwHVya(rmT zBm5b&c__aR&FgG*FN)F=ek=;pF=I~YG5KnSfHTllufhbp0_3$Tt;DAoQeYY^8E`rCU*8L<|0+lb4BH(Ym?8P^z#H3msY9^Zt^M!{opw_Oe z_Vz<5CWZMw>=6>u%}Z5@e+b^xPjZCFe}D6P`5#DMQL=xC+X+=|7P+j<^W6repMSh0 z#KR$4P@w%RV@{X=2%oe$!21`&8>uWUee^UZ@~y?Vm~4KK5Pk^RG73sd~8 zu~v>{W2sbgtCwNZm!`X4{rr+wQK7t8-ik{{^g5V;=AZEcLK9>(a=x0fnF4`(_qRhb z2Nd9cklLja`-d<`Y7hFq@#Oyn8EVi!BlLXv-z41=E`(|84!E3F>abR9 zbhM29Mg#j$%}aII;~w3m3-g;lWneZ88)^`z(dcE^ZhMwz|}n z8;*d$2~v1n;8j}>tKB_ID`&d;>w#X)Zu`kh+>3IaF25PzY%J~PI$O=F+eHhXFf&_z zH}>|*cOFKKOSLPPIo*C|wq2~^(^tr+m1u6aLRit+8r9%b6IO3VLZg{v3r= zM(y3Afqp6usSDjoZgXY8R_da~otcjU2^3XNr9qg449jkaTj%F2*1C4B-?7uc@4 zp-@(@0$!nL+|Duvy8K`RF*E$FS-(L$uD0&N#oL0F&^FwMs#N+nc-wkt0whV>y!lzt zi3KsfXFzZU-Syg#xofo1qQft-gW*s-M^;X#ZIrHw#j389sQQB(*(Da3 z_5*9QY@p~r+V2-qM=JIMr)AIOaiY31Ductludhq6RYh(e|uV7X6CSTvj~NmNTgM#KZs#?D~=nxOIc)fg2bh=F*r6|BhWb_Kjv zXyD&4_jUxT40IUc@C)Bs5w5elLNLkNoV<^cq0ILX_uS>7@-!(|Y_k^7ZA}=Z*wyb}OLXN{q&Mnji`4HFuG}0{vtF z7(uXrcg%Z{_a^7Ly?MImVvUs;a+B|Bf-dxJ@oMTyUnmCa^WuA-=zbrWnjPMoGz@~J z7yD%-tFM>KgGqXeq(0T(kBjGo(3|6}e5x}$YF2C27rR}cOuw-i9U~&C_*bycfZ*Tf znu*k3(MZ|J|JP5!e>m4>^~la@itzP{E7^IpVlwEoh~iN#R6lEo^7JNX3rl0S#0b-D z?(PeK%&A2!4aFtCQ3CoNQPY&!p9O#z)Z^L`a6wtOFNfL{KfeT-1AbYG#B+YZ$gw~S zXU$*RAf&1ir~T$#`=LkyBO1oQa;Wf&ummU?;Ya5+-h0+HS&n*^hvJEl+HjQps2Z3(NL0pa{nzK0<9xOrs!(Ue zmb<2^Oj(4sv z!-L$7dWeK~!-NTj21Y6hq8%vDGOOm4G^RQx8%Th*I~OuryjuU(_YRwbRyW-KNW}&4 z%ltKBj_Qqn@Xh80eKd7`RD)Gf70xABg@D*iit{*0BFfs#_!wjuvdNJ}0&`8Ib10X# z)mxrEA*%i$j98ml%fHYT4j~M!r3ocXwx7-!H@yPu6nv^7Nr`Hkec1BBpQe4DC8~>? zkz;GR<|uF&_4p&S4D_1=AymmHk*a-k^Qv@Q?0z%zBCB6RrGGG>^CcI@7u^HBFBG+|;Z)vTbDLhz!Y&^Ig;bQxmX+=J68bsg@THJZqN3go{#(|hBGZ0=@S-x zBrdWh(~D&+Wv~HTTrC0NudNJ!N3<+j&~jt_+0g}RHc2a`uirO$-~5F5&9~7vFXmLw zx7l4V!W$@yc`8z55=G&^gWJ* zjF%Wv7JOs)7}`=I3iH!*rYr|p5fV>*)Wm=={Yp?3=ZwX<8Ei^6&?fTMWG*Ti>$bWm z3JG|vEBF8gDPJr`-(xuwJbn(PUpW!#$A1N=BAlsN3OLtMTWU64s#(`pUm80!s+r&@ zQ-(`W(!W~eaGf~gxrO5L-<#E)Wwro^@hbcuprt#+1G8&E3gax=kKjiK3IEVIByplhQB#$`62apfs`!|}EwBI>+( zRN9oX_*dU8WxUAV{f;8dw7eQA2OLYK9*AS4=dqW2B~~!!yV%x2>{^uSPlh4Mgg0dAnkkQ*^Gb5Zlovmno|kZ#^9f} zJ>q>|AYJM8c+JL;jq`3T~bxU-(x zR!8I#9~Kl4FwstW)yZQcUp#Tyt_Vu6-!~A^-X*n~KZ;@jc}mUA{oM_!i_daw-qJ8i z(~*UKE2FvP){C#<(mQ8H z^b&dWYC$y->k}sMh++1(!ax^`AmOZpS3Hqd`z6@mNtP`b2F?K!H+JmY)9!rnWVs4! z4e_%XM&T)aDGz=hC1icK*S?cc@5;r*kJ36UhDq{DF^td6+pVov7+N&L`u0=wjs1Ai zyr&N6A!fng@Y)g(QZ$3i+(wK|K!lf-9IvWIhW~}9S%c~gy^M76UTY$VlU!)Y{-?Dq z8I>Qg)V0-c$OAZ{UZak<zH2|3{#iF1ao~l zakMcF?nWOS%Hh*i&kog|3{3fKY$!HMw7tWv+9@q*KdKY-wA{@?1fe5kh9mgg0B!(f zhDI(8HJ9@yZe@q%X84D7!i8B63k$1%Z@nte4nETdOKB_p0@>*j$q!7O!q`VHaP+~& z@Thia(zFTu4+%N+30ul>Oh>+n-m(CjV#{;vA@2M=jUJ_}`%yOF|tQs!w6gz+D5iYTSyA@Lq9(f^7U$@U?tTR#ZxHL+W zWO*U<7R|pCIo~Di){@&C8s>BhIbM15?(&RUCDrvyUD`pyy85Zq^5bV+E@NA-l5Hs2yd%2f1bV@rc_tw8#M}&&c;$p0@7tBgVbs z!-mWH9EJY5@;S8BA*((Pr`|&h06$d?X{{p^v@28JwM!eHg;U*G!lpo`@#-$5%Coa| zs}Ac6v-^D)Ja#spD7=BkxSFaDg2)L3cMu)B8=oeDIosd4nyu=Bx9Wh+bxK;fk>arl z+xuhr*`o5l-^0RJ^~@#v4n&1pQ1ynVqi4Ac)d`9w6$KSqvM?uV*4SjeN$Ky&*q6Ss z$nsDbW~0<&1$-5$!bN(6N|^fH&BWwpLf5P}FNp@eTdGUi%A!11MO}USoF$<$i0tx9 zm=@p5RJkZM3_*&$Buu@C0(Tt8k7fJXMB^ZuvMH(04r*&THPbiw$NU^st5!BmIp4%> z0_kCg#52NS|+Xbu9^AfJwg=U1sz#O{+pLVNTJ%7*p zyYluE&2d_woV**r+LS(KP=2w=<-i7?Fe&ei7EyT9O2xM^s!Q7bc_w)@SzLE{596*H zj|F(=GLAt;7pcegAcmKhFQ=VxXYPP}>Ep}=x1*NraH_-GZyIb-zD@S(02gKoC4x&x zzI2*i3nt;R2#~pe{#m;tlQB^@ebk#FRfS_lVybceCirrUDOY)L{*kr3qsLHzsxpt` zXNBGCAUfk0ylCW3S6-+KzRZjrpDqAbO_zr{DJr@OoX53EFMBY{F?7$)HD&3T-1kyx zZJfAtu7NG))gimp*jiUC(?YLgiq(lq)@4hRNxPH_I+8bG{km{z zfLU?UYj`*oTxr*Gs|L?|NAZWYa48$A7H6PCPS3Sz-1}x}5)&?c_ampF)keaUL@+i~ zeEDOx<+36pd2I+W{43>&C~Y}LUX``FAV*Hh*$hFPCSP1{jF(rm@by$RkskC-`U|NBa_ZUau7>z<;Qg0qq_Z zCE3(<{Or1LfeVY*mX}9P=qdP>dnl^jnCWF16kxe(j`+X@^_z9>)3;%PjDMmsnFxtEZiK+i#P~$&%4atcL&y(Pj~FSEjUUrdBMF7cpad5mTBGc8zP# zAbnQ%eh&SSd;)&WROh@5h&*TdBvQxB-Cj|Ay&3b4_{5USuQ9ish-Q1-TWI zcxXPnVK;U8Td1iHVmlehDq8cB)D$TnQV1<8=%jO4x&hs?b+eh`S{z3o1q7z}Z!XAv z$&Bn#^{R?Gj7Dcc+@b&}xY-o{l#GVBvM#Vfn{3AY?O{#jU_p!dl(y%1I=KAn&f;Ft zF*Pb!Nb6BM*o&7IJbnc=&f6}wY|+wW9(DyDnsHmafJ+CILE zIBw3wOpW{tS&=V>R1^w}-x5JHp?7bo`^HEZ`I|5DFuPT^m{qx%z3u`&zC1U>eK{nG znv%+aPk(H=z?E^SH6LWtH+sPu*(n=newC$tK8-Otelbn>!CQ1zU%TFtE#nsTu~#N| zQGE$2wI&Gcqih{;fp@my8q8SUO`YFMy--bFAKtD<)47GTOr*+9luxawjbe#kJ7=HBalNV{DL}0 zQ}Sgvx#g%L&a7(|IgVrF&UmLIgsXRc7fFk6|Yi(3xQJ2m%ZJdI5`u3%jIz-4f82%TQDgujYs<Qf{c!;BJh^G$ayU5Y)o845X zMkdjF;$#gu*Og~rMyZ1Z=QPI`2+myzg=qw=wwO>p8UY z@+l-YOLv$I?>1@1n{|%Z7t}Tj3gEVu3ntnZSRRHlpyk}a_^^);>+FSwozw0!A1@6I zjc_kR27+xoFRhkzi(P`0b~yl(Mp=ieop;It7;}3o;vR;bm7d%ur^3awQgR-Pd6nH} zoNdlD2*m;92)tPtrWvQ#buRPKbX=7bYdkp}7m+iIc1gTBE12#dIAV9)RShYWclIlFOnfyolr2b->zUTK%>1~H~5#8OAdYm5KCrLk#v#b}|e;E0CTWJaN8)*EX zCODlvzGQTwh_=-x8gO~Snc)#9l*#11yTNiHH#jUUJ2*y1enj#!-Ko=?HoXCGKZgt( z03-Z^j?<5PXk~}i+RE2IQPJcVUjdJB3|<`12mBg{C+4z#?MpD##C&)n-9hJ2$KAJEKU8Q+(b6gDxhS5qRTg{@ptdw9@i1!7KPR zHJ@IR@Xhr4C*AWK5k9sa_Ek>rJeCjv%9q;1(2E_Cu}knGyjUJC_zY&%d>WzSW5b_5 zJ!Y`d2M4kq5`od2FRxWc#fv@!+Ib81|e z{fhh62Re}0V&OZTz1d-5*3)ZOh0P>bG|o3LJKa0&)%X#gpW2_7bflI6FI%bGxe*ka zu)Ia*q4-xuU$nKpaAGtVjQp}M9YxyZty#r~%mht2jlP+)l!o&vIi9*l%gv)sN5)7x zXva60#7by@hON!kdWZs7Gl!IX{b1_Z%AddvXMs=E@xFlNj6`(7jq~gX{WyhnOwj1Sgx`10;6g-K-LDa<(J?KHesB;!Oq2`%c|hxQp=gnBndqotUvsm zZs{0gWg>L^-Jkllf9tz&l&X}A^7y)@OxjX%P`ZO)(CHsGxQY6a>Isa#hRpLxpWXt+ zCTF8aML=^+yhNu9q6oT-^B+biYG2pbUWt#F^;yaZU0mXXp8+jLnB~ub7~Z-qNv5@h zjho79El&R5XpvWPf2hYrj=$8S{Hz4(@bYLu6)w?^NWgv>vidICHao><6@0#a>oGj=bVRcdWr%i= z42lb*d>YqhN}#{)iFs&|j(1fiv0Mrm`E@rtosE;wH6w9c!vf42?~JB6PG=y{;*nUX(r6m>wT%F zFQe2LG+G>tr9}h}B#`z{gnXpoFarO9^nBuPho8%fd_4K4N(BIIFN6ZsCL%_9pYv|5 z(jX6GzB=wy=)9MFESOL=rO!{I_Ero(Fmn)4t4J%Lh47UuV@A1w@Sc5x);bC;ho>K$ zISFWrJ?rStQkM!=ye2@%8T~VG^S>PFNl**l>#9-`j6GqWjKOB)dP@b3J_0Vrehd^d zd{xUQR9jQct!KWc&h0DX(g4P_)*^`jm;%A29s9_6`D^ALr}pa_Tc7H5SpJ>vs^>R} zGCahNntk(^GJF3s%n*SM;yJ@bIsJF(f8K8Te-O3(ud7o3)fvhn9_n(Dw-X}l_CiQU z1EXOL-Q3sh`mCZ{brE$C5zb}$pi|g_K3KEb);R=1wpqBCoq3}0)YfOXi}b<8b668| z?j_pIHWRn;j&jyF{uae!^G%wSzEslHx}{vdXCHL>TGHYsj<3~UVBW3X$qKC^ds&~CGGr3|8)l< znp|D$&3Bf$!98&{*0nlLHGqah6lVxkw&bW@9ye`i30pZY%kS{eS#*gxmYlwSb8|$6 zEkFysdaCzo9ZGXa*1i-58l5RgdqH}q?e4ymrlHYHcDI&V@3kp+JF3U!6`B$C{i(U# zJlFDLu+2@=mp4cpM!5}j4mc3dN~KCC)e?PKcY7zed1O9%Mf{nLAgzr;I8X_!_z9VX z+FKO^N#1WxSPE9xnk;Hui!Pny#LdXToKw}7J`7~zgJRiIzb$2`*{sZ5_T9b0XdW1= zPfU8BlHOTbYRC;UQTsL9dG;GDC=%;w2|Xqb5QGbA2@HL>U0wmN_dZ9$2#Z;?Uq9kP ze)#N9H&ZTD{+N!!HLu^vQ+}01?NZp9lVB!M2^6sd)sW6B-`?x&+ejpfN-sCp@J$9O z+G@bI2E>~ab+~tiuygonjz=apebZYg*li9B&CBXDC;ECuC6e%nbpTUct&vnugf~qm z<60J`M|VMU&@1et%+EF^&b+C-=S8cl4C66*Lb;qQ*q>G11u;B>=N_Sx_&P{PkqIK4 z2k`-j@b@qDb`&@FnrW)Ky2~n@xHc($8Zi%8>kDpVFcpsS`mEn-EyB zkz1!s-OiJS!jzvT-eFvVgM#)XJGRu7Z0p9)!_Z%OX0(48HtCfeDtFU%2^VU`$Eas$ zapd?^6SE(r^d&fo1c_gEjODbpXv$T!af#!Rf>$rQzEF>^hC&7r^m&xbfL+^ar8Rgb zm&VgSfSIycA1U^19$brDXRoL901G+M@gMmfEKRP!);T_;-00wY_R_BK2f>GXBfI#+ ziA~?W6cntQi>`>H)WpC!%k4Fk7 zMy%Yz0Ie^Kn@=-Jgr%OwmMDq$F3gf};WiMSf)q>B`P_oR=Ix93Q>hbb@5E3~UfIV& zr?gf0ejgtj+~IGbiF>&1?tnQ$i6IAa@P3uA&wBw2s!WIKn;~W#j{-xtAuL#pl<2B8 zN-jmeG619Kxb9K;pg}#O2cH5;$cqi$=qxKfWteQ^{$4(Tn^aIb3Li#dGz?p9@iGL*Hp*zF}a;go%y>7ytrQe^rCmS~P%+6p35qmZ)3dJ_W9 z={DpEuI?W%2n~w%4XGT6if+LrdRr(H=$%-{$Kx0;sJiV_qUau2 zb5$itx5ekDuZ}Eg@kAPukX)&KgIP}`+-ZJ#Uk*!EH$EI96?WgbT4Y((yBT(vH4Li2 zT&)bkdk=0ozt{%8Zx0)E+NelJ$7GNVTtv0;Y+X=VY_6BpL^%KM`OCi&hf|&--T0w< zdN=~pPtNdXjIe`CU&2j5jf}HLobkoeMW7{QP%2_Kr_5oAiiC8*JJP^Ooff>-rqe*p#qQCK+tb8j>gkkIRt8JjOL+KtXEb#k6E|2ks?Hktz)vCghQdo~48+M}XUvMwZX*L=B*pll{|X zH|DfLUm-x2TTND8KwoS7^rbHYH(-yibfeU}(zW8fLbq2@fMO>4IF?xhjN~R0J(*pM zWp>ir9SI=CFK~TX(8^6$c!Ex%yqsCOZNoThrsV4H= zV$z4wHsWWsLZjEoBkG)dgS#rvUEtKG#-)ghb7*jdI`>z;lptb#fvZ8*2I znw@+r<`lsJ%q^d--E3+v_-<)(kC7;!mskVpfh%^_hjP;_1o=D-PMR4_W%iNn(7ED! zf&^%@v{xZSLdq=jQ&^=8AKSVWO5KuodyLl4kPoSU!J~!8q%Rd>r%G&BGh75_00e`e zRM*KXx?Nd4?Ty^NDuf-cr^t|I=vo!dwi&#MwnC5gW~I-zzW~*g(uSX$ZQHh3^%Zrs zn(xiN1?A;I&Te07SMm}%aZrPw`05(75f6C~kh{%#1f-EWBO&0J_Uq0gQy{1&T+ zpWa04=7Q13I{>!;;X01LSt&r+<)CjLiYvyr>Ws-<8t2>2WZ2}FKR4E(A(jZOO%{>% zpho!AkP|I!vJ+lx#h~Xxt}=MwrBZ`vfBp(Og+OjrS(>aa zp1yCVWKo~fHRO*!Ig3>MEg&GE)eV}-=f=##lLErD)9_m-u>3a{po9XQQo^*n1|lO( zWbf|tEVT1}oyj(ATx6T)Wlx#gHFg;C#7q==8=$K-t}OD3ml#Ri%+hiZq|U&=P}=Tw zNlitiZl%|z)%DCh`P+?B+9d;$-#3Z*`Qpr;7xpA&z9Szg%e{@FevYKB z@#PBvK7Mjy;%udX5QrMl)cAxMLs8FWr4k8=h)B=BN;T=nZA->ltR+7&@-Y)C5{Qn8 zX>?&B1%zg&ae}l`kn=Eec>fY9JE!DM7~Nft(+s~l*X$1}FaJR$kKxUVHQfh#EiL!Awq|NfhdUo1_=Gw=1zi5O8KWd;6lV&B5a{k|U8_!B8n|9bBW$I_x45|W ztMyp|UUNXYD`Awf~c64#bid)4?w$@pOMve8gC+j8XPr zd@@{zuG|li-=x*mitw?76Agy|Oh3X0Yu|eOhBZ=5(~&1qsys#9pMUxnsYH?gnTh-V z;J+OH;}-cR&+fnf#}NO&I|K3hSLJbTepNukH5k|nn?sSZ*{uB|jv=a+f@yJztSM@$ z6*hxiNfxF(bv4wgINuQOkw05oq7<0b(Ct|tl7Lt>r}17(6qf&@UXCuwiTU&Xr3a`k z^j10+uMclqMLvv#54HR#IH^2Hqdb)`4I4?Vu&zlsGlP0uAhyCpp5pMQk6K1*XsE#XVJ%4PHy?UH-Z@u-yWhz|9pmgf1<8n>1 zEG1`_!L#g6g1%xs&AbLZ*aHUrcl3F^#+2jUGc%SO(|2eX*BrZz@zM;GNX3H3VzEm; zKN7qPeRVWSwsvAQwnwGUhKne1VHPJ4)INf#muQ1gk;ZnA1c7H32fp^#>XSGkU=srD7 zBs{A>JGDSaBP01~_p=yN7(VU7V*BK@@7?j(iOkTD?yv1uuL*424i_|`?NdmR^~O_f z@1m)Bk(2d{*6-TH=qIk#Ijk&~`{cm$D)?K=Esl#-2=g)cNZ+RG)q0=vu8d7Wq6F@3;T6(t@DL&D7OmGzU_t>8c#gMM|B`uc^i zcm~-gpk2`qpX)|OMwX=ZdPU{=pw@>=`TH*Ff5}Q-qa7kmM8N9HxNyG*ygjH@8zDva z?BYuWP+6OV-#`(o7X16Zp!HO^5$PfszVrqMr#Nq%Ni(T5ZVA^F+5V3& z-8cdtp?xKG_LwB^t!H*8d{PI`XOFYwRp6PQm{I3}N_b#&9cC7;`4 zpm2^&Vb9d{C=0d2Sm(@6p!9gRXI&L*-ue&ubQ^HImZ~H!LfN*{l5HPxEk1Ba3S-8#i|^9}Jo>-_AMcU%kzC2@CYTI%CIQ z1pA!)-CRsKENDvQ_TKb8t2=|*X?S@D>Ku&v3tr)_`5M4yzdjBOIs2Q);RV(tOh#9} zEZ1{=GrqAXzIN(!w;$ye7}8&Z$MG1fj=)#n@F@}B!f`Ypn+0>}%{Hx9`!)!PV2bqX zk1xATR_A8W!MDp>NFt_hK{TZviWg*;qFYn3&}F#aa-@C?9eNUf-3MFqB4^tq^2ww> z&CBaJ_-4&1u6YI1DdOXjl4T2cm&T>5uacL3)r5qDA(hrihW%9r{RTM~RKw`=4IYCi z4&EmbuBMTYYKQXQMSDow0%FrRYm#*h=bd{ADh2NI7f3coJKtO&x54qRuRcwhd_Ibb zk0SN58D|spr)P&R);VCM?TDh_MUNaYabhUImm)BCj0yqNhR@~5KNYHoaP zD`Uvhq|`i5r(&V=dGFyizTUF8Z;fxutA54xj0Dt-kc>6VaY?O!5+8&$Mq<6Q&+#m6g6?vy zq5CI$@T2j~7Qw@zqUAD2lS@(c@;RsL${w>-c567*R!@3@*K0lN(LU({Z=QZgrOkCh zzJtzX8uX&!V`{m#Yv7(wQvHFYo|EFr-`TnK(46m7X4B2~@v!|pj>|BD)s~yn57%bt z_FEcDgtHXJiz$CTu-k12*Dl84b%v0Gxv5(?M@6;-w46wIa-BPFq7+^V^1#{?JPiyy zW!B6pb)((sKXsB7>NccaWgstEW$68lkUjXj|dGr^EduC@@xpFkPdWpBDCi7}byu`BMUu1Hy?bwW^8(U@0*Ks*A zzA%?mi8cPvEuQy^_Z^ViIO3>0`|{fts^k=HWaf!m6!|lJTqJ)Tl0Qr&Fm};(xJFNi z@|9+AWT?GVd?{jk;f1)w!ZlWZ8c8F`V1YNweAb?QNa)Y=p6^sKb!pt#&8cd!FBe0= zKT23@xhOy*12b*24cijGcdHd0Xa$Sgw!Vux@U3dUuXSOax=J+NKVERmd-Bz{7?t2u z8JB~B$XMwm9$tT=kEQ#V)ncymNnA@gUhU!TrxIrp%mlbzz;vX(oT|;I-Bj(UKX}x- ze4cN~AwR)vwwEc@{BUiDN{Y3vTCB6OgPPZgSv^g7iP|L@tFf;}dlzs6%XlVQ(KG*a zv;~AZsIe&XUYdkd21?88Ya%5-JH+pFRX#lqqyr+0j@K=0hik6BubpW3&o^*IrVq^( zG>~HOB|@{jcw1cY2zq-vs@fD7Dy;TKSK+BSUMO18A?-bOQ&H<-cx*b;OpDpq$UPmE zjyg@%u$FhNBblUiL6!Bz9DVsxytP|H6~h8YUJ#)d_Ronq#$5!L56@TZHuP`I4=)g$ zztgTEitw2wvpy)~@i%-LpajG||1auH1XJViU~n}s_2oUL%D3UXwejb|n9>76(~s>~ zW@l&x_g80I#L5;5pYJ|?``)QG*Hf37g8YdNwq}#PU(xMSw3=+)2TUeyVuB@bf=(bw zN#OkX5#ra-qLg5@tve@zkfsz|mwlCrGurluQlJEd?Mc#+xVepjyT%x!gnVXT|5aQ| z1PhFsBVaep9uxPg=qmeJGPX_%ujU6DuV8-J?q&K4-!fP5Z$zZ&>LBXwr@n$F%Px`3 zi0PDc>_K|Ipkt+yZ*$KTB&IG&F zz1;bOWDP{mm}6Q5-!<+Nw)sy3^RF0*^TO5jW@AUg<5Rm^1Z^Frua3%I&O5o_EbzrM zNjLnoxK-YYm&8@(^0~0sf6{-pdRgx6ghehuvXH%hbHSlpleUomGwGW;gzyOm(5Ch< zJ1`$Bqs3PM#~-;e;~7$B7F`q!KPzxI?ky)z<|3Q-`d~EPDo4aW2~pa$dX*oQC=5~sBJ`5 z3~f;)xvm4Rf06X3jT_zM$TUY^vLX+!81A=``DUuTI2f-z<#rQ&kIx*-%7K!|!=cLg z?JH5-t|RZZx~Plhw%@QErFHzmAPnAbn>0=c{L4oAzft76&FjL--3agFn;hwAA)AO! zX@y5Mj6yU($OUXO%QO~W28Ji4EXc z%*Rut0taEM6pg83j{`m#HpL!5} z>iZg-R^M`?(Pn>0NS0J4n{J%(hmH-cCU;F@jQ#iLRfCNl94*}7xIa}98et8k<-=qg zPD=qiQ45vMjYIiAhv67GV|jpZG)xRx6vcZAzcUSKO0R ze2p3)NAS}A9U8s&@19`U2=J4H9eyy5J!*95yvykqc@!<-uYYJAriU!d@ikC(t8Vj_ z)No~Cw)I1q(ag$|&R&Fg|6&(}JtOXkt59i*bvUC=dxM&!nWMWsj@98l(lB48D!z z7W-HJ=_)Obpt`AxxBn>8PihA_U=+IOC!7AlPDH1IrXqnyzvV)5`K#Kz-F(u7HnQVH zY&bC!jqC zR>AE5Sy7riL>-6ss+Qyu9%*k)sW0(aPO#H#W_ub4cCEz)?uHU{Lc?lZln4M1{ zSYIH?2SxW6Tw+HtfKz{)z`V(Y~E!*Aq^>HKDDMk72VXs$a)6uzmOO$Cv%R7TiE)N|Mm5%i_pB6=R9z zcWoaI~i@&}sq81W2nkz^f_X*)}8Ej8R>Sh7L zIMto~v_2CNVuH%iDBF5cCLlypv6G|IJArKO?Nw1O`?!Iji6A7u_s}57eCT!c2jf6uOpNI$$W; z#}Vg7&hxIbJId{N2N&dEPMLwVjYaioQ=Fuit`Q6E!NY!( zj?#zt6u(>Pn)Khpzj^mv^>Sv}x04LbKg&oZbX>)uEd9x??dA`(MPvo}R~)V#Yf*F#+ee7bG+*Wos)g@xt33_4 zx3##M&PSMO)6KwoTDWN3n;8-rhak!7q#-E2Z!5GG&{3s~;_&d=0+(C_T1f!NM|= zpgSwuguxiPV0Jj);y~z|NxhS3A|_$mNKF}iw(TtPs=H>TKS#OJaylHF5OKO{bSqt3 z8eGQvWng)uGB~>H@c?1fmDBr2oP<#O_>ajedvLq%4_l|pIc7q{r>9*yYS$S!&c`t5 z)eR1wV4L78L3lUfDrP=Jcg6SpUGO)nTkL#@!Vr0N^@KuPYW9cA1NQ_1KvQu>aj0L%h3-HJ@{G-6THxn z`X)#y#O8M-yr=uIdyQ8PCSX4P$?>PmnDM5|rim|nGbBbmrDXpbF%(jmks4VYE(paD zb*x7~IDWvqeo9y;UMvJeDH=Zy@f=E;8m{{Z9pIOg2WFGq+O5HAYA=Ydy<=ksU=V?W z>u#aFA+L$z#_U`rs1dhz9ICTW7Sl<`R3poU1@-y1_1dV_ZJlOW$zZ{>L~S=g?#R24 z6z@F6Ek1W5Ndm~iS*;)X;o8LL<-sU()?7KA!zIFPg|)W-F!VL*)pZSdAGo5#tlowD zj(}w2f;C~(4p!tsVRacT$b36ge_flFwj>shk{{iWU5)^u0TO0syz_DE8E~|x_h)uj z?|QbR|2UE5lYkuKRQc((a?_>xfq+R5D?QVxS16|Lcz50UNhzuWU$YtEAI40b2`3iXOx z*AnhhbNULa0{%i?#Sam2H)!OyatK~0x9pbBw3~g$6f%t?Xgu=Q2&!?mTy6@}nNNsE zv*&}jFDI6}soi|%T2zfblO2~lm8Q3t=c7bxcBJ|Wp8b5j&}x$2q0eEkLaDxVJskWr z?Pk#3$0}&(;*7i4T3pZgN$~Vd%S35lwGQ9(5JZhJRN&V1nM=X%`j5-W7+fbc$eBGu zkaUhqa;j^)@eAKFz4uq`As@;V~U(Cgl?t@7I`uzxbwc-*ET)f z2y10q5ar;&-2ar}N`6UyrYX0|(&0NAleT+v^Pt(Z?!rLXuYy~~I8F<-tJA%sV z15epL<|J9s$YL$kaUDxE73q7Z9`{Q5BsNCWx&wp(sKznfe29NLEi_+uOLB3vtaBlL ziak?V9)^NoJD8k|hHoeDcY`apn(vsMkU=4-E%}eRi@VSN%^VCl!8l?zUS)Kuqc|& zjde-=_jOmk*w0jpZYYzS_s?E02M>M+hf8w+G%88eyE;Og{meRaU@_G45#<+(Yik>Y z{G_~O(D^vwb8bcko1-Stzp?p}G}n}LAy-+8yj(pHh0*lKJB9Zd^p(KGqSeItXxaj; zo`b3!%>}C;1I~QI`;+!lqRJDZTS?6^u1U#X@@SHd(LG(gf$3UZ1gGFqDz>!rFq^}f zPHELMyhlld(KcvmLada6@yi6KxD;w)Ufj$>aqAq>D%h@**6h_M%ju2z?}?AkUB^AO zi>EnUi8zn^ca|2qbqqC?e%^E^_l$ZAquC~MlAo$K?eAC@^)zM2SQ@i4OV`Sp>B_F2 z5xLqe(6U{M9Cir#Y}S78S)y+NpBaF7U7R_`A%>G$4VNo1947ia1Jpj4l+%eB8(!TawKe zj`8Y9+UmkfU}c4XmLg&2>l6CIE!Pr{Ubch2rCB>Bp)!1Q@n@9F2sbK%cy?xZ18q^& z&ZB!hHKSfD+u!5en^|0sJ$Rt)!a`x?Gg;O0EvJs96lm$J*`cnkT3q}#zwBHprDh^v z-mC0u1~>1vnJ-iIc)Y@~s9I1pXW-H{0E3eGrsS=3WL6FM#t+;bjvg5@7ui2G=-iGY zb6owqF%3SiB5H;@?M_Kg#?G$y%iuKMnn4qp%IUCgphb7vC_&cTOa2?Y#M zbe2LF^R;0fA@m0wzz|qI0|+HQi1-aWRn1yo3#()-lww}wOg+k84l|{NfmMsfp-@Q= z7?4SORd&?DO8^LLW$?h-$flnGREXb zG|B+{1F&0DgG+ji-P-@;0z6i`#|J0XJ7i2YaG19twx*=nJ`K5+wuy4uvx_oiaDKC;3L1HS$0Q;2v{RE8L_!X)anH}D=Mfl?xacp?@*@o|_W<9xckWG&2CGtx-XEBs z!W&GATf*KQt=?FW-FZFrCm3;)roJ{IBRdfaKeAr3`uJULa$cCEnwWn;F(;4VeH>U=z1(ZJ;$g%}i_D4LepxZsePQn5>sQx7sy|CAbK zV8?E}ta?25X~N)5GvuUS>zxWGr+{gh9>1=hUfR{k_E>A)CZ$~!8eci*RcYBlillX< z+G2t#*FyI}oe8E9Po!(zUhQAqYukR7l9NzSM3gw1>+myXlJu*S^DmWnjsn9~1a;@@ ze2}+#wASAlkI>X_91>(y)p9=1!y|w8u!~`%Nj&#u%GmR_s_9v+zkWYo@8NSh@2e{X zsH~fzBsCUZe$Dw3#JtWW6SOiT$L470nyP}qaoCt^K{b(6uU0lJ=VQOVx!rYJ{dC`< zc>Hi_pL47l82s*TMCTv{+~PpjV(mJ-cHyeWsJzj@d36^_rtgpw{-@qR@3&C1jPGjo ztZG5t99r9LMilr7S;}s8TU2*|P4BgPz3QFB-ZPTx{hwKIoU{qK#%($oTHtB>VG^QxZ4`pRCw=vMB-p-o+x-!GiV zwM47VEB^j)J4{{j&fpuGe=Hxde*Uejbnq?b?YpSuWX-i_VVpwhP#n{>-L^}S&PY8q zvd=^z(zj2T$2hKzqy`&Bed@Vf9aga2e$sS0cp5}#JT`YaRrHyepPABckJ_s_kVg60 zQ03h!j<^0{h%~auo19)mxfd;)N{})Nf$&GNxQ@zM)hPLS6{e%%TPYOji>2ZEYO=9G zT){|iv8JXRrPI#SXqPY8PR(Zc=cJR$8E&6o8(%}Qi$!u-fejis2l6(!HUs)G;jO10Mr>!^T230HLe{)cDvWwoOoHB9a6&+cSiP6cT!=i+S zGp-%0^C2U(m$CK1C&5U0;;CWo=b}|aO}BD}>#5|<9BO0DV3({#Vg{-Ro@aT>AIBSK0bK^GRozDP-pidSxTJk7VQFUV=Lt}ZWbso;KJ zl1as2@4rhK?;UdZrGM$e7R#7_lF?;4LSWX8`y#9S;Mmh?B9Lik+4q{`Qk$R0yDRMQ zE^mN%$Tz@5SEyStA-W^AdB`tq;8I|br9~qc{@$HU2b~~2grnCN_zGi>wRzSYZ^Hf8JNM}_!Cyu z57x>n7}?K$-F2!9C1YU6x~%q-F>mbod^kH?TT<7n(BFs8!NbZ0G`Z}@YckJS7Ja@vD0G+o{uvLO z+uBeM0fF1hGsNleiU~9ZzTmdrl*4`RmH#Y&2%*AkJbJqvFUk{4i$ilXd={K;PSWyw z2DB&7I6ZH*!Btn3%ljvoZk^tL#*AE-5<)v~pS{LuxMaG-**tvrX_e_ngMsut%M(7A zm3TR0fxmb{ijzC$L1lu8O-){z=eMUzG4&mNmW_oJI+L(~z{Xu;hK-G?U+p>NxIK zL(cD0BWDf@_!7V8n2t`CWjz6)NKF!HJ%nv#?rti7uYiiWREE?=l}0A1H45&V(Ss@fKp+RW z8}THUv6*GE;XBFoMf-f|@MEB;q>yKSQT>C#L_@))P*mh(*sq01VBA{mYe9~k`Z!_& z0VsX;L$+{)_5YTF9&|s?BjEqt%iT@C_GtHo71bxqT2i+kz=TQ{N8ET&#vx(IY@1;z zSgon#YUN;a@G-D@ch8@SiVtNrh5S5sD>lg4o4{|uI7D$vEE9FAo^P-ey`APCX~dxx zsHk_vYG>Gdz8aLQCpiG}k-N&Wm@?x&+TXtPW}8GBssI%s}HwVjbY9ie=V zH1U@4>pOYv92<+#((l3bf!r7O5Mc&{?sMA67ITXBJhPMqDM@M~2feQ|c7EK}J;c5{ zt|ATmgoQPuU^838REkGRMt*KFngq&-Bz!*JnhL==jBjp~U0SRLxHG z%28)e(3$D(5Q^p>fNMQZM8pYHm|+SGmYC#Hv!OK3F|6y~R$sXo&mQ34b+J*fJrdSq z-5C+1Pgqn8om3a`e8co}d}5J`WyS8*lQXDL6km^RJ1HF4ohGXEiUs3&`p0 zD~705XbX+Tj%8g98>lf{VYiqXW&>cn08JzTGTsp3Ikkgq9U`hjlDh0|`cgSF#Y<1x znJ`o2j~Y-OxTzVWX`r#u$oDd)5Ns;JjfWp&=L@fkA-S`Ug&m^8$b<*kuwcr*8;yvW zUwm;B13#8om_A<3y>qNj?a1@Z>G;A36jQydNBo``+tHnZ{A$x(+y^l z{+m5gi?-fq8My#2h;5IT3320Ic(Ec9Qf(eyguWWfAL*QuUX$ohx zEizE!sC`bB;JU+-dvP`b@>9n$npheyf&Kkm@i%LRbGoO~XUHAEopN z@j}&BsgqH3C0?M`@!6)eq}A?0j&)asuP$&TS5)pp9a=|5NiBQH{&c@Y(`PHjUg&!u zD2{{8kmR7i=vAE}kNT%SsIQf2^3;u>j6cHz8uAIco z?3tYG5OFd`zDKf;LPkR_F^ihtPrDD^wCFL>Om~el;ur-Cb1&hlU zF6X^LV$Oc7Ip$%hBB#>bbEeX8V31!|BMPEC5a*Gw$;@w9?2rDX!3}tB$!gNlQ!T9@ z)dFkQibJJDm>iEq{raRaW&&Ow2ERD0)M`{UQWveP2C@iIfx;hv;?5A!c%>ABix{=A zH)iIh)K!izX5Tv^h?BH|v*)}VB??)^AGy>Hhx(Shy{Y_D^+Ml;m-mg(W5^r*i&{WqdGLDl$D&X5L7fWShwKg3oArgH9T>mqk z9U7S1_fr|E0CO8GM)FqzCHV;!4hm4y4%$T{z?8+KCVU$(XC(ouZGVcz&GCU4D9;8J z2;D~WqN1vDC%??Ve~zB1-r!0h_7(KsMEs1jljw>>k=d2N$4bEVlpMn!jbr_H8wc zUz+Hf0OB_E`~QG?e&7lrkg(wjQb4{njXc=29$0MlWuf8U9$9X6&AHzhun<3|f_ zzg@S!BD-}jK-bFbYGP?|H*6@M64@q$m z!kR%QTJ8x8W1@xpyj$==)szV^76H16I=h7j>Lc^~mmyfmJPD>IIDRhSA(hH>v74LG zq$*`(B91VAeG0vi{^KYm8dNa$1lnU!^P9&=lx(JJ$oF(_f1gy1mZ$9MS?iDuO_2S8 zn%Vs3xhSsDL{YjOkH}bQ2@J{6r*GR)Z}7+3!ya}L@_$aDQLVI=d>$qiM_&15Om*a6dVuRs+U~0x!B_F|XLBb6E8^zZg z?us0Ivh1xyM;Y+HZiEGyLEg%V44*^P1kHw*q`KJxqFCi*U+w9>7Q6DB%cc2(^*PZr zDClhoQ}q`t@@=Y@A#%w)!>w!q88Oizl}dE6+v98jKqWcYlO1Z6tv*!puGh;Y3H*6s zc4?%efbN!A4Of8ynalrvVgs;)n?KLY`w!DTOy%Lpa9}1%gA;%7Jw9go_a#Gq=Y3@| zm+P?IT!I&bEva(v%ig08V?Bt?AC(Sm;z~Z+F-(#P0x$cyPqWfUZh8L>UeoaF@{z%I z7_-S5bc6J!x0h_RhEM)#al8QrklX(K^C;c-V)krUND%;GvV++z4ZK`<_Sg<^xq|F>UR!l$8&-aV!$sZ;*AG=D4JMqGytVVmbS|J~{zfcdglDI=My{zFtzz`=5mP;!CI8Ah&_csN3E)A;ox zPSJm;0wRy6pER&lSf0uo((Hda1a#EezcJ<+nDcGlpZ*eVCYih^PX*l%5HVmE0Yqlm zF3i+=P7e~k1~#0LKa=)sznR|HPCv6oxa;c3ByyR`PvY5sxO}Bc5#A&M&@y3$7cz4s zS(qS^%VAW<=IZz);{+(OzNhnuaHIQc$ebADeAwKyk2FtH1SF624_hcDxj3HY?;kLE z*IvRe4w6Uz$E%bj;HRGZcn&oMO4?LgEbkEn&*+2mQ2$#ue(LSP{=V{2uBn+BE-;hc zc|WIYKhNHnsz8Z2we{-2*w*xgaEy^K09opAhDdrjyu_eo3((q0?>F))_v=D-Exu?x zUb~|ld&8+lNd6z3-rY@_m7e)Z1YnHZOS}O-$;9P$^o*T1s@|yqtaW?IGq^pB;e$Ntq%tS;)(b3UbTJN&4K*B2R z7r-Ptc?wU*S_jj^&!*!ok2A>b3F*Y^ND}}9teLrXYB zJ=o|WO_I1*7b;Y@oTI)mPlQ<>LMq|$?jhf_yBpu#T=M$F6TZX+*yD_HEI@i|l373B zj#5fWM3IUEG<;W?C%VyENIdp;t{RoaTAcW?K=6Y)GOyCa*17o0X=$aEStB(hH{brc zMH=LR{Qy`J&4n7v1?=NL%7o7kb*v#(gZLltW^SojNe;V{@;KmyqJSxW@nExcVjzL= z{#{kpBw+MOGB->9UjzY>-ft_Tzu6nsNCxytNqkG4h`V!VN|5>6C~ZF3Je{16;%cb@G_Ny9xLJLM-8ICMY3+-abfFhP{!blOghL z0q}hb3q#VgQx_WkIFK;kKcG5d4Im#dZweDoyI55&S+CiVK&k&xkm%i)KNXqn@Y}ue zv#sHKuB5Ww+uSefotV}tP0_l>uHJq5NEq)w0XH-8WOq*(;e@~A`Pp_$a**Kacw`X2 z(f&`7{ZR7V-0ATvf7E*nPTWhOAG21X)&lk;psB6Bj?=UrHu|64@SOT&|K^eK+XsUq z+};WB^rgbbbebfU0lB5YlqPYI65oUV84<1|J2w-$RQtdB2M7lr1f26-N#b`Q-*7ug zD9W+{tL7Cg(9m(;?l#gnxHwpCHC<7xVPw0?-VL-31{^FU39!b!e#;OmgLkjvlmJvN zKHR)GXmgs=+u7N9za-S(d)EKXn?D2vPX^Zk(3;CVZ-8>8f6yq=36V*VVJWc)cm@-J zQ=_GT>ZX6t@O$2iuw7`7mF(XP5x@L@A52bTo2teGd%kF_DN$ljW3_v2=pykP#LtBu zFfu_{ce>AW8@Sa}Q(c(>yR;2PBY98cmHz`|Nw?b-p$B$d3~zk|z@&%?b0Kp%K!=Vs zFqtm6Y?{(M`ZEr2sC@Y6unU1jou#NJbFXx*Cz_}I1k0O^C^f6O=pX?g%T?3_^lV!| zzWD()`LT7XvP4k_ih@?g!SRe05EH+Atgp|Le*GM9)bZihfcMAsS6&Kf^+e!vV=D}I zngIspp0mt#etWWOB^ShTIAU`o!>K_91OV(E_Q?L1VPSaMV{d>DGd~Ur&xp;yYA3|N zY9#COBmeuJkqLHHzJM9zSCE+bd3G-VRKw^Q{nr_3F4kwppm9|kI`%ST<;J(_C!3B)Pfyp4Eu=jLdIoeU z7-{@&z5z&!w@9!rm$M(dI)la3A6gYtCiGXcb0m5Zi4ZX#S6JJsb0d8wVt!s%V{2h% zmf*p{#mD#RYX#tL%F4=AjoG`KkBHN~NL)(TG&aHcV>BbEu)joaJgo~zC{%H$Plflf zu{Av_P;KCMV<-%gf6l}GZex%)jW@XEZf%&4u+wkun22-xY%(3XcgYV3??Htf)KF|m zN!DL(3Fz)<;b2t60r6u39&%oHg?M>kdCO{==M^kfq*v-bj(Pgk;q0A9ZLoHx$Op@_ zonVYC6?9M<4&c{X$^l=i5UkE$ff^+!56(NYZOO=lj=!)op(H{ASOE8*rBo9#|G}-x zsqN7xOh*NBa{+?15H{9I~vz#r%0XSu6YfC>UZBcaxvq-hGz040EF zd~1S=Eg2oc_UI1>@Xc>|IqBWzNwPyqzowtj(KtjziE(kjxGN?3{gSl(xfLpWRXRvo z7hp_RPnt1C-u$Py95&_9FU5eHNJ=XG?w}?fjbS(61~XCZNXS9vtp79*b0ulrZ7ubC zKxP2TogYFPP6agT|GPL;!I2J}-l?%f$N-nRR-0l$PoF(#go#J$);+ew_pTkme&{Dt zGUJ?gD?Gwt|Fn5+Ct#q_@;~0&17#Er#Jg&!5RzX|pC7>K;3v3UWC9Mx=i46vW3F9+ z%RhtIEX;4^;~h8?qI`AJhZj*Jbm1eqwO0 z*I+cmhxdBm}{OyP)78>tGgfn1qZ~hhp!F{ zfoWf$2(aszr&2~N8irPwKqLFBa{kw`Dw1E4S-K3rL+#*5grzaB`&+RYyDlOM*sf9t;O4ii@CHr)!K5 z8;U}J`|E`7S2zWd9}U|7+dj!!KN806uB$hWY7u3AJ4s;OU|#X}9q`-zN9!|W)lKp5 z*-@UDuYkn!3o#dg8r|DiHb6lJXQ6|Vm>+iwBIco3e?O^Y=j(=;qNqbOb!EJi}#r z?PdBAjYRjW2X0!)QmwN$x2$BHfjm(DyT_HMzBh)3fPer<_zI8z(N3=L4bLYp+r<<; zJVtve18~Sc=S|q4!aHRKqS8~=sLfk_N@hAqkMuvzTL!_5IP%P7`-JR&fu8-y8^5Io zhtzy^247;oEaY4i4M1PVOaYL0c<2%MFY5Ckf8^JEf9DAG|F%UVnw9#cfK{ANE@ru6 zn)%d;zyWRZ++#`4_DcxsE-KLYuCU)vx_`7L%~YV2MDdyC$dsAp1!!B~KUDhVNnc;H z-hA@&*vXXIgd*QN9H0k;C6U%O{#fJ<@#0gzCjnq7FZ5|ae*e&!^m3{_zNPL%aQwYp zPDI=db(rFS{utdq>ttcEI0m%-L-j3PT(|)U-1Y~yW}GP}u!*rE&1m-9#J3*(l|}{R zdhQyF`22cz_y+2k22>GqPibZ>2!t%YQx|yZ19&Cdb^u3a;5=|7vB1<~(4tVBE`tJY z9K)|fv|j@6%%6j5{-JMSMp|!Heyyiq_0K0={Clq8hylFb2d*$Lx%W%k=>SE2^9^}A zkqGUVA&@!SzL&`iSqTXVV`F1={2@AIKy?9ZLYg9xYBSN7=q~xoK=cVH@lF7ACy%DGE7<01x%J0!Wg^MZ$@)y%uI~~5{5oVKPOV3 zqCrlS_k=7W#E9nTGcY&~Bpg8qyw#lNbK6z6WMnw0KqxT90;eu8`ZRqyUCw{tGzPV~ z1yGg3HlG6iTYkk5Tx*D}Nb3nimWhD_Ig4^VBuGHw@qrUiL%rLR7g@C-oSY#<^{LV< zR3Ja?f9U(7Y4pf9u{8l)z;Xru*4icn>^Jg3>N%OLX{~^8VRxiTbjKS7h+{TCQ9S}p z{P$M9i-Y;$J3zv`Khrv!0MS-u#=Q&9af-bu0kGx-{ln5hqSxc*NgJj5fVP#J>68Lw zNoo24ooWBauZN--1QU9BeFHZ6?BOx9aDWiDM3RHzcrr(fgb43}6*?r4+do32QEyyQ zS}52-f$*-&j@D5i6?l^7{z*O5XRleUw=0AYH+#3&_cX}YlytoKqq=Kb{=Xt}kXzq> z++0~%d2)Q*@Y*90$T_~`8;DzEiyr92lc^57vd9v#2Oej6fOR+7Ve+{)zZB$Lm7l|g zB}VH5V6Oq?k@Wg&9E`9<1frW-8bN>77O&>pA#Na1Hbnjjurfycks?55$A?;9uU+z_Lexuh9E3M{SH(F2rpK@#sX(_M(_J!LoYS;o2rcXNARm^y(R-$no!K=}^?RqWLbWJrFN4z3?v zELj$vRUx<8S~8i!5LUrxm)AT>j9#8aV`I7yQ*HdaDh+q$zaOLuNXU(!iZX6f6x7Pg{Q1_D3}{G+76YADa;7H8yG$Vmz7-He&Sh;lL6To){SU;hEaA;ea$^*a4cYn+y#8h5~%; zT1n@8bif+d2zt|sz=%xcQDO9Q)wb0^gKEBTE}kum*}dd-{GH=E{i3$5MA!5T2b!cJ z@iLq^XC)VGo8U1xDi&%Q5hJMOsPRKw+a<7qZT)(cy82K^>nt5H5Gs2esa_anG8$QF zts`5DAzQ6b%J7uJx5*LWE+G=AG%={xY^~55bD2oa)|{%pQj$Y5m%x;qy`t%!mv}XI zfT8GQwKrzsc$!vn-T!DbkPf%D&BU=Py~O>U=JRtq$J#b*gW*a}ji~no6j<149~I9W z^Vgki^WiHFe2q@aL{O-~s|2BA-azfaZ-$%s$h(8vUo|)h^4{T5B)mba7#Bi-C%N=fnlCqp^=QN6( z9lh$#Q#BuPv5^r>dUMS?lLXquL?YkjQtxG0cR;`{#`4?M7V~P(Eqz)w?Lgm;0wT&~*DF*#yYNMb|Vi$>kjs!dbFSxc@0QT-JX9V?ELBU3zl`r4`Wq{6mz zrJ~ZrD^!yrT@^8ZORq9e+6$+DM*`-66brhy?_H414YT(-bHxtNR`ZM{dWAn1{KNXz zro^$j>S2=|5zp%?ss?0+-}r^jy|2(wXF!88A)F^^#_@y-uv4LXt=uZ2nn;VA zecfG6BGRr3=$Y~uKkjmYoq?h7Xk}7m8DT5CT#IwnQ@hB{zc~;^(@yq=2R6m3gfXFJ2)Skrk9yl$Tr`u zCpI|W8yj2HT!`#x`JJeD$BD60hKs|2?k3)2uz69d6?YBO9p$CH3S`rfw4@g|MpjnZ zOJGUrr_Sf?Dl5slz#BidxY)64Rw!(LBC^)okeI>3GS4NlBs(=IDS<*to$WX8OyvOy z*8~<=1VtRra!#`{b>5#XcUulb#(_&fB~Ox_ibk7)8nJ)y<1YXZUnNGxH)VT zZbA;GLIqeOQW!{&X`BAEO5vHmjGEQ^gIn^=9@lK zuNx~CE5>Jn(3$s$wb-x`o~+|O0lVq>w{3P^)$1&N`DICtN^|4GKq1-uK6 zprjDGm|TejG~Pr2?E(k*FDD=$Od(8*+ESI zI)z8=J#W+0CFq;C5i2BPJ()$dc2A{B zi8t!;V46_XngDJF&v+$uy$_vJl>+^0)`E>1uustUTl+{SFkgeM=(EJbDSSK3HtsLS z!gG?<4$LA9^@Vh;@0m~9ky@^4AG0SU4IG_61T1^ft56((1F_4b&Q#1a$vbaqUt2)2 zuf8RpS@TlTHt*>pcawGDAD177Br z5+pOZ$n`F)0O-&wr5)90?59D8xFbSaNQRlD^s+FylDvqXwJ~}K3tj$alA)k0FQmi} z;7MwrCIC(ZA|!b0%d@+W$63m`oNpGpZzMONWcel0HhBlFoGLNh!bWYC)DR)qEoxM5 zGw%&JH$u7r*{vC+$%&5g*=_F;EXI$9RHe88bOFSt8*d@gpM%hrVRC>ou-(QuVTv|# zCq<_*10MWzi99KyeY#9xMjNJ=Wf%p>6t?H(k<=eCOy5*)5<<)lhZyb70m zw>$h?5P$1|FyUx`&Z~s0CFJ8_(D}PO5&*yPpKUG)3Etkxl8>3kK8tUhH?UnJ6M3zp z{v5-3(UfqbP_>^yu*=gMET(w`garU#@`oC?KvxS^;dp`sj+Q+;=OMMpelOI~oF!15 zS4GO13+0nk+7Re>qYT(*84Cdc#Qz^C%P34&XUa`!lD2i~q!GouWq0Amu89I&_4Ac0 z&c!+osA6=2-Av*)#A41K2n*CrPENYIx@u#?r6I@dWq7yX`(*7Uv!DK` z@fSxvyV!IkoEPVtj>tQ#diXxc9 z`p2c%(5*7HAFZ-qQ`~mB4qHXR@cuVkCk*x=klrm>He=o=wVG|+LNmhMd4{F>UH>l0N3i4-oe!`h(yH zqIqixKBtQ3FE|+u$(Y_sWVYrdco5vH?EGwJa)U3|@f{sOe^^M(_JKu02NC=xWTD_< zm6a3o2kQ5kx8E*oK8EVsi2|v*QI8j)++0MK-B&GY`%=37{h9uUw}mbZ{L#ND?2Mw zl@^m@MJ$|#_ZQI8QYWu*$*tNG<07?R}eWDPFxx@^*>RHpKRF%aN;QJWu$7e z+@mW1M*agSING^5B=ecs+u5-oJu`Lu{dBpNSe<5vkp!)Sd0`|+`x@ybN%5_S0fd|? z(g4aezJ1$Ne*bRkcwYD%epBBjeNEOhh%_L=|=q90V|*l?s&Jod#24WTjca z@HZsr1}V)FHUQ55A{F_`9J*)w4C4ir?ru-jPTVa6wodh^zUcEC#ACiw!&G46cSuhB zhA|>?2V#yuMTFw>i8!6Ne>$?t=+1}rvnS(FEwN|fQxV#6 zxRpWMPLc$ZqrBc;yP3c7bHM(Z-@4e{^pU)IwOjTvSh7qQ~6*Ipt zZ}tWhZ6)5+;QY|86HDaANAZOIFAAJJFCnoZncE30$&mrTckm#3u8#WgjV;(a?V1|O zFLvi*`8{%km+Ea}*LUYb7c>l41qZyZ1doRYsi5DnS9I@yOTHq;WuZq#1|5XVF_Z;3 zhe;e+Xswf-QnI?)A-|*tMKK|-xQYuR06R}PH~JsU6Y`fH^UYmwW4hMP$So|2kt1rU za>zcjNFZ}omT-T_d8S9XxYmuek}l=QoL7=-q1!Kbf>A|uJk8;7!3QX{%?*QB0 zS-}O%-rgcHI-V$4Ndi{q<9gMk-1adG8nzY#bv)7jBp}zZ$91bKq!*0Be7etmkvix} zioLt8QWonni;0oF(KV4x>0HyJY$e2))aw|gk~>Bg)M0f!#RpWQk}m>ed*2*UX)4PCdmPznYwGt!jG9m|Zd<53?xls<#AhP|)lBA>$pB3FQW=`c1m{d;-% zO4$fzJbv_W0&kb&I^iSt)NEG1RT(V$S4Ny+SzU6{kFK@_S5gf_zk%ss!3^=by_o1u z+FsBW!2BbxYyC5o*M$nVYcYW0S#4!rLcOKftAn@P9$HmWsP^XVRpl!kSAX7IPk;Mj zVYhUecK%j-niu$iTYTM7rZofH^ej6QZDowAKoija3W13wxO`@93Is?ppBG|GXo!2V zVOCoDsgFLRChOtMi4GfXnV8t<7jBDp+PbaHzC4xG0e*db6Y(pvR^XyYWsYs@8gvy{Q=x|X>UY? zas<4d8_0;MmLOzGcAGxCWv0tgaU<(jfi|7q%50LAp`PxKF&BqSdIifzX`O$rIwixg ziyi3Q|EM_#mz2t(e9vZg$G=};f2QOm87#4Qf5VT7Wd}9;(%>quWH*-pH-gV}M!c7z2!9MAL9mA=W%WHce|XvufN+dm2VSkJfgg=iu@$#l$S+96#oOv z#r!L9-ml-&r7yV!&nof++|sqjWh8Uj*lD;^cZ~NIy$QIb%d}f7=N?@76W@>h7m)>^ zRkNpuHV6>{90A>WnOFcJJ(MvyuDvtw=GY|sD%(@tnku)9$zHJgsUGKjY-2?>%wmQZ z)s^LkpQM!DnjNu!65aYTah5{!BudG`T1n&X-QQKa8!{_hLGc&kwCN3j4MJh=!6)c zp)z(!$>^nISKmYiJ-j%y&*|s}=*65kk%Y0dB%z`4^%^NDim-KPNi2t8>`~?)5y`i( zh)PY33f{)wyLzVT&cgi%2QVMwC$J)%!x~i0SK_U4*-(BBv07aB%WsTmw4Oghqy}*g z#hR>|u|E99#g?~G*HQw!*~VtEYQN{+(+UJV)?5L^7%~x)X3aH;l(VUQ$f9N}K0A|# zCYI0cm>SRdRhCh(DP5mT-TVn<_kLkvQ&ekDsY0krsHco(!U4=wx0?u|ZuZ#7| zYW=kLX)?VCEJ~5^Ps&GL8|yEb@^p)<#r8W?4lPlVDtAHNT;JEjL<3vS0HUiRz7^4S zN_62XKoPEvWK6RUJw{_Qc%B;sVt5BY3~1=KHAZhv$tqOCF=0#bPOExg(1vZ6+rd#y@_dwC^P_mjlJ^ z!Rd)hjf)=QG8P zzDbS~rRQYDBMXQcPS{J{IJMR5Wk48iU(cX=xAoN=Jw+#F@ zOPlA6vXZ@uUi-xnvr@ge-rJVF9Apm5>o17r#9Mxh=ACU{CkNFkWtzRG%3FP0$&+exzvArznVI*^tq&waLFUNXJ7Yi<>Rp7(NT znHy*79`07K|9*LV&wg9KzytL-Y5%R8^(sKR4;v2xer|A3BWsf@Gc6(gYKv#*Q;;*? z&3BtN8cQTpE6@~1pY!=$2%T6Y4d6uOJ^97)TsjOS%mC0D)lMOLaPu;F_S14JZtcb< zigml3&v$$hNVro~M0!#?kBTQ-cl|)2yq7W5lUN193mn`yRt81z7v83&l)c~ zS>D%xvA<@3W>>yDv&ILx*UBLtQ9a$-yG^$yfG?-d+x_ zCyEB)Y_FiG0(rmAdpNCGJ|Z1^IV?C3A{jWReM}M|1X!I}eiw81bHfL%dmIFJbBB{s zp6`w{3+=ngSbqv7+Ue;Xkw5H*4@b~1CwG^}B(_pzv!3QCGgv@hs2!!FTP?8M{8SjY&Xi(8U72rCbEl6%Zynd>&47G&mt(SyD!$ZW<) z-R)JLTNV@)U>xwia0NPRXpaBc(u}&Ql-;AD?T514GvQXRTq6gLu>nT=XA~D*N!3aL zPvZK<(0yjLOc_)k*sOD-$o({F))U2S4NH9${aE0W3MM5^vX(kX6rs=VR%xR1cHMHM zZCCs#^__sbkAY!qCu+s3?}l%^E2&=gKv2${h5|z&AnM1x>(#fRLalS-LItl23N+46 zkxRDm5^wMvICXW*aW0F7`|E`JVjK@{CKq1IC@EDOR1bP^e|!?>&W;>|@d3KBLXA$G zh(WmIbLHn*4rDH_yI2*cH6)D$8sqJ<7&4zGCnd;nm_tdu@>FRl*&Kq369705<$R5W z)<$9e2{Sd<^FR!io!V0+vahDbX31f&-{3vvp=K58N|9C8Mweb;Vw1giuJ%`8JzH#9 zDKzJO4Gj%oxMD6}Ku6b*3ZD`niHB6`Ko3bo>C5`D!yy6&*}Z z@q7BuT;&3Bn>=lDO9SJ?*tFM>a039qJ&?^}bOwQ$R$yY^4X!VZ7)^(8rhHVg_@1ww ziN~8qS^olu5gPbhs#Vpb(axcQ9EF%A0kmE%UJZruCIVcf!H+%mr>yFE<@0 z#3+M^*dA$jy*IrMrAjD)MP!Mi1I;7gj6 z^ga1mq=xE%4E|tAj!KcPVW8uenU)*l-;c90qUlEY&&S#m*M}9%O!EZ}RbS}y^U}@m z3IzMi?&;eT-dSU-s+B*x2z~V!=o9{80r#8-j4IiGTqe)H8+?`h8Z0r7O$jCti7(eb zYbH!T&nM4+Ui7YY@?1=FnBp2mb5x39z7Z|wpY7UfiS&(w_8!g^l;)34SA``8e5K;# zpl2Hzom|*YJV8ee5H)ngIU=0t44PXJ?|%uHaJ=WD^V*i<4cx%9K**+LBG_4sR>hz3 zqGb?fv(iu`9otez?kNE2(&AiJ-{7-1fLet)tVYv~=UK2^Y61;vOgdK11JuI!Cq0Qz ztLYwv`(e_Nn&@asYPiM3NQ$05M1Cy?6s{*2 zdhQkR=YF&Apnz_#DneX~j*#)x0cUK*idA1-$Rt;%#@CfhC1ZM{qqp7 zpNUrnqtQ>}GFl^hwZs#9DL{1GajR8kW4w5azCQ5iX^F_JEId9*?}zPuA*Qkpq?1Df z_UiC+KO_RS8~jJU??H=n{9B=Zgpc5G-BQjuP`H7V{{}9N#7K(`8T@n$>iI%Jf}wMt z)KTz6bV!1nUjhd}Um=9tw^a9_Z|X>h4)+I!(9x&bl192S18pWi4aV+`Fdo2bW=7s$ zxnVk4EDSJ zAQ1ldhyb$(3lGT@7x4JbWAaJUGKar=f)MfxVbVL0e+1X2=j!x^C;oT7l{T%k4-xdP zw)9%3h(Cr1?fwPTj6ENFHVMMVl0yRspWMXv0<@6(378o(;%}cSiD5aukv)%-0F9j? zq|YcW#Ryv*IJIjmw}iT8l_iiTy6pahr=$=gnNlIdJbvEn)trez91M-|1I3qt-u2&K zXaLCf3Xyh@5dviFBe^m+#}i-0Ka*1XqJ&qn7_6RVRbND?kL2sivQ&V*OI+?u01=BX z>uod3+_5m}W+W7W3Ff)^nOd_{>=1kTyr)$JU{&+o+cUz5HZ5BiNk!N^%ym-~eq6dn zde<~R1{)ASGAIzW^z8@+9h+oIW3!!V7(D^jKbR{orYZ@#P|_`6b*mb5qYI1OnoS~DI_ z(XN~_gQv_#y1nDa&v^KQRB|WV0;6-f7CCE}&_1(iyp{z`06P2wRAC{yi`OqZ^E>~iTNcVa##RUNZoonQWqT^ zFfLi!{*6E7>{t+y0|3I-+iZqrw$?iJA&`c^^Ac>>>{R;;(S4 z3WB5&-kK;c1c;$YwmZ_F=Vm!ktN6c5B>CmIgrby9jwt4@yxZ&I)Iks=Y86-C1wbB` z3lQhO9c$xT38z2W^pUm~01rA!d0QG!YcQ6XKCkm9jP$!CFX;+Wb%ib{60?S+_g;cl zaRo_$;9T>NO4eKr{;8+aBN->L6OFMl+V}Y$wv6h+#}(9QP*!l~iOG7C z2Bj3bfK~M){)3L^8{3NqCoCMqpewKNA&`!bjRmvXkNyOhYcwrU)E%EMZ!d1RbV@(A zBmf3o!9z@1wMWOs2es|zhbs1+l~Kud5BUc$f22W=7ri#B)4_m$_yib#;W0G2SrfLD z-BTxeE=6y&O|f6Y^yNnUYc76Gz35NgoVqI{Nb@Dwh{RXKd24oRaB}VN?A~ESzhiQx zkPYL+_*Hj+;#mOx*!#%+3`wI(XyeJ+G_De+ zwhG--3sdEjS3MUmb8-J%n{jZ_K_FC2pvwAU$5iCqf0A2V$jCC(z&9Tb1={!sZ#!DvC6&C+X_tiXuw^ z>LmgCX>&@}h*C~}@7ZV%Tv6u*Belg-DYwSnX(4&+>SUyaohN6dDych9!5a>q@!q#6 zydpIKN**)^UI+>}Dx0<7y(?CXwl{cRT}X~~BH!75@YY9O6GfSsA^}f_D0#cKVUpooG110P z&#Xk7XEQxFQ;D!%HPGOu9w}1fq=(Y}a2d=|__jvnmyw^lK#1Y^91>D}5tA z&YN12`4K!@sN23R)qL(~uE*H!Gea-O6l}}hNH7Sv<-^aybPCIqK08V(JyjCA14$r3 zRBn)#;+R@7!tH%$PPT+f=2G_NN7?6c6k}2$(j=9919cOsAF4h-T}j}AlWQ@;`VF|J z4GMi^Qtf{P`=l18o~46IA#}OSy>v81Pm+)pl%0=`6LJ6hKTx#g(ZF%8h|tc$9i^su~DFDTjU?lpmZ_?#K^$7Bo=u8CHv zbBu}%iYEZY<5*o)7yoHspIlYL(xD@^`jb)lZ2Vp911HU3-CrtaX+fyV*~vP)gmp&V z!^Yg@Typ4a?ZM9DH&WJh{e8?YRX3!RWN z!RlXkAhyR~U=qq^?_BzV|Fx3mXY?@7x)e|MFH(<5S7%LOQAwKL zn)XOSZoyAaeAPsHiHA*eghwL8n43*UNlsK?6UuM(-oz6-Pg+JU6+=uIs%o<7dw}KP z{^q^mHne{=QGH|c1Ooy|2n0?5F^tP%LtbNwM%8p={$^O2Fy%5O%BFZEljYb2mf)^$ zDm|}lKK)gwCRh3LVf1|Q;@j!MmANXB1DZDr+)rQhD+nmfM!)yP{Ak4d!au8<$C~W( z*wwoN8+*HW<#_t~eCEj^S_nix4Tzv^alBT`4>#-=Rcfe_b6HfWl(o`1A86G}G*&@Z z@?6)%uCn+yYy-Qz=j%N-f{uyjqiszc8)`TOqDL5JaYH;;#-AcO$6W}d{|&jwu-(%! zuVvV)xte18*SU_{?k9Tb7p_9K$Ln1I^fKq&r9K5^-PTZdqv7v zQ**#`r(=ISddY((uA8A@kkJqAUaNh>1o3Pc`%tSj>k)~?FVk$4z8KiZpir3OpfDjTV4{73^8FDtZ}g5|*~Mf--%nrk4>U7xpaQG5rsXwH zmEQxk3q%`uAW^b4i_HUR{NyFU7uL1<>Lfh0Rl5}f zrypIa=HC?{V0z!5fbx7KDRx=9Ysk~I(Ak_~C2SQQk#c3Le5~X88fFeszvOpM`=#KvS;PIKCt|k&iY-Pt%>U)5 zjVu|q;LcaMz2!7Bf#HWqX;%l@X7jprjIUug0#3H%xJl#cQ7dlwU%&w$!Ruf7pJgqI zdw-mr|4zCGzh0h1-4El?IMb3ENPbhKsK`eeE|~Y72V1Q3da+G>A70W!doJ0<@h(e{ z_&j|Cb#ca~mkFruYIR^I3OC`JpF65;7#L=h)u9uc%KB@yGr0N&53tB zGOt`cFXG`7#r-eKH!FQgSC{*v_qToErS5Ld?{#2vUa2-my?csBm7*L{eB91(=aX~q z`OOd;pV9_rgSzdu^@)0|lOvb5>YF#qg`U;hk3Yuq$dcl31ljm}+c*!6QLfi*+A=$N z%ieeu^r2}_kblIHhs&!d$}#pp{TMu-CF(?!3YvRgON$dD%0z9-s~X>;AYkhvN0UeQ zS0fuTCA@{~uXuc@l1N5tuT5q3fB!t+I%#AJ6g%%-6gD(>RmKX4rELpqEVX>2y3uBl z>LJ}(m!S2llsm^GV?9+Z_;Q-JY|vD__N#V&(#3L6wJg8r9t3iq=B>zU<)bDqmTM3B z@TL-;k6-ou%JVlB{%EhT5JA>*A^r4=l0VNVXl z1m81RGS0Fd`c((k+6o_dFklf z%J8aeSkZ-TlZFqtq)k5D0jAF=KPeHOao9JRCY%rNFU=pAXDrZ5*LpWW4_{socmFsi z&{%1t;^myF1IwVVd>z(NEvQ&o$45C+q9)!w`F29x^TKelm-v_nj_v|Z-)u{5PUyw|+ zv-PSscM7;#FjtHG)3V&vg(XtEN2CUv{KI&YDbAbq|xeBg~X0Ij$tu1fih0*MAKu73@q{5CBhU+io%8$?8U!p+Hqr)q}9S@ zc~+QR#Ogf9wG%~=-4;OxXk%5&;bKP7@5Wt$nw2((lcG@bAww;-bv%sGwOH-MR)#06 zJa(0ngZbLdm+cjQ5El^6}H(>4vmai zNx&i!I4bzaIFe9!RM&29zCQXsV|t!OHfqBj?=hZp#e-+Kl2UR5{ax$ZJ5QR^p3}3v zd});d(_^M}Xs1w%GcmfMt(Ew-fXCJ6dsqHh8{d=tQ^&Jq#e75lgKh<-UBA}UwMdmm z7B~gc)wSBpHrTCIO^8v?x?I_oG>8b)T)Zw<8eb;f?lPDMkwJXLf#7i{BW3t>j38_LlkG$z-YDyGHSD`xqV* z>-HdBha3>YHeZT>(z=QocYj@|g~9H|xlB}>Q;i;dU!0%sET*Q)mOU{m+F4DlAsx{TS^k9EuXWLbicGOR|{jtAb>!6J%A_575>&e zkhk|}D9W;{$2MG~{5$P9{0KQ)kUW)=&Xqbo2e_;?!Jr)GyV2*e$;N{iamYm|{AYPc zz{dmgDiuhs0ACQU$A~cKtUZKDlM{r)5@Mii@UeaIub;vH#E3W$e6VAIH9UwoEnPRd zo=?n|>w;rZ2tg6;Ei-@jovUB?pHgkU$C?Bq0i3=N(H^%cC<- zV4Mg?P{#-f7mynSp`!f1+_b&p2%KYOwGG#*9v>YAH4z#H$cqq#Q)Q)A_0RegMCGC$ z-ijq5&6%J?@L7=m*P~F`FRcxw-&~$`AA!v25VcX(>b?ayB3&JIA|{&U;Y-3G%sgqa9{iwsKmZ)*&W zb18#7rY*1IG!I?x^<^fTDPViZ+d%YZ;OlS0f$#s`#7(aIqML|CVY)v3({TT40dUy& z&3|sKcn_j)13&>eez4oM);RE<|FNwuth&+L*v>8zoK8iO8wwihUzh#M#u7%I{i#@C zVFKxh1yug_1`t<+vyDXlSF`_fb)=Gr0os@oy;0&m$(pWc;oXO{uO63iq- zBa~e==!G`<^w{k1GashQqcO_6qMSZgySww+-+9RrDyOHXJ*ut078D@vklpIW8YP{* zIcJjY?eg2-%R>O$^ORS$lG#LDTu + + + + + +ELU: a negative side with a floor · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

ELU: a negative side with a floor

+

Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/elu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 6 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-elu/logic.js b/apps/website/public/widgets/nn-elu/logic.js new file mode 100644 index 0000000000..0a925499b2 --- /dev/null +++ b/apps/website/public/widgets/nn-elu/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from elu_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 9ce6cbd76c05367328ef91c3620675e88166d8d6a2753769497b0e483ec38a71 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-elu/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABGwVgAX8BfWAAAX1gAn19AX1gAX0BfWACfX8BfQMIBwABAQICAwQEBQFwAQEBBQMBABEGCQF/AUGAgMAACwdfBgZtZW1vcnkCAAx0MjdfYmF0Y2hfYXQAAA90MjdfdmFsaWRfaW5wdXQAARJ0MjdfbmVnYXRpdmVfaW5wdXQAAg50MjdfZGVyaXZhdGl2ZQADC3QyN19mb3J3YXJkAAQKpwYHSgIBfwF9I4CAgIAAQRBrIgEkgICAgAAgAUGAgICABDYCDCABQqelh/kLNwIEIAFBBGogAEECdGoqAgAhAiABQRBqJICAgIAAIAILBwBDAAAAQAsHAEMAAIC/CycBAX1DAACAPyECAkAgAEMAAAAAXg0AIAEgABCFgICAAJQhAgsgAgskAAJAIABDAAAAAF4NACABIAAQhYCAgABDAACAv5KUIQALIAAL1AICA38DfQJAAkAgACAAXA0AIAC8IgFBH3YhAgJAAkACQAJAAkACQAJAIAFB/////wdxIgNBz9i6lQRLDQAgA0GY5MX1A00NASADQZKrlPwDTQ0CDAQLIANBgICA/AdLDQYCQCABQQBIDQAgA0GY5MWVBEkNACAAQwAAAH+UDwsgAUF/Sg0DQwAAAAAhBCADQbTjv5YESw0HDAMLIANBgICAyANNDQFBACEDQwAAAAAhBSAAIQQMBAsgAkEBcyACayEDDAILIABDAACAP5IPCyAAQzuquD+UIAJBAnQqAoCAwIAAkvwAIQMLIAAgA7IiBEMAcjG/lJIiACAEQ46+vzWUIgWTIQQLIAAgBCAEIAQgBJQiBiAGQxVSNbuUQ4+qKj6SlJMiBpRDAAAAQCAGk5UgBZOSQwAAgD+SIQQgA0UNASAEIAMQhoCAgAAPCyAAIQQLIAQLpgIBBH8CQAJAIAAgAFwNACAAvCICQf////8HcUGAgID8B08NACACQYCAgIB4cSEDQQggAkEBdCIEZ2sgBEEYdiAEQYCAgAhJGyEEAkAgAUEASA0AAkAgAUH+ASAEa0wNAEMAAIB/IACYDwsCQCAEIAFqIgVBAEoNACACIAF0IANyvg8LAkAgBEEASg0AIAJBASAEa3RB////A3EgBUEXdHIgA3K+DwsgAUEXdCACar4PCyABQQAgBGtKDQECQCABQWkgBGtODQAgA74PC0GAgIAEQQAgBEEAShsgAkH///8DcXJBACABayIDQQEgASAEamsiASADIAFIG0F/aiIBdkEBakEBdiACaCABQR9xRkF/c3G+IACYIQALIAAPCyABQRd0IAJqvgsLEQEAQYCAwAALCAAAAD8AAAC/"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forward(x, alpha) { + return W.t27_forward(x, alpha); +} +function derivative(x, alpha) { + return W.t27_derivative(x, alpha); +} +function negativeInput() { + return W.t27_negative_input(); +} +function validInput() { + return W.t27_valid_input(); +} +function batchAt(index) { + return W.t27_batch_at(int(index, 0, 4294967295, "batch_at.index")); +} +const __NOT_LOWERED__ = Object.freeze(["forward_batch"]); +export { + __NOT_LOWERED__, + batchAt, + derivative, + forward, + negativeInput, + validInput +}; diff --git a/apps/website/public/widgets/nn-elu/logic.t27 b/apps/website/public/widgets/nn-elu/logic.t27 new file mode 100644 index 0000000000..9b2a8b838e --- /dev/null +++ b/apps/website/public/widgets/nn-elu/logic.t27 @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Derivative | φ² + 1/φ² = 3 | TRINITY +// #8980: `math::exp` named a module this spec never imports, forward_batch grew +// an array with `+`, and every test called a two-argument function with one +// argument and asserted `result != undefined`. Now each test checks a value. + +module Elu; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_ALPHA : f32 = 1.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const ELUConfig = struct { + alpha : f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // forward(x, alpha) = x for x > 0, alpha * (exp(x) - 1) otherwise + fn forward(x: f32, alpha: f32) -> f32 { + if (x > 0.0) { + return x; + } + return alpha * (exp(x) - 1.0); + } + + // forward_batch: output[i] = forward(input[i], alpha) + fn forward_batch(input: []const f32, alpha: f32, output: []f32) -> void { + var i : usize = 0; + while (i < input.len) { + output[i] = forward(input[i], alpha); + i = i + 1; + } + } + + // derivative(x, alpha) = 1 for x > 0, alpha * exp(x) otherwise + fn derivative(x: f32, alpha: f32) -> f32 { + if (x > 0.0) { + return 1.0; + } + return alpha * exp(x); + } + + // The inputs the tests and invariants share: one negative, zero, one positive. + fn negative_input() -> f32 { + return -1.0; + } + + fn valid_input() -> f32 { + return 2.0; + } + + fn batch_at(index: usize) -> f32 { + const input : [3]f32 = [-1.0, 0.0, 2.0]; + var output : [3]f32 = [0.0] ** 3; + forward_batch(&input, DEFAULT_ALPHA, &output); + return output[index]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // ELU(-1) = exp(-1) - 1 = -0.6321206; ELU(2) = 2 + test "forward_basic_case" + given input = negative_input() + when result = forward(input, DEFAULT_ALPHA) + then @abs(result - (-0.6321206)) < 0.000001 and forward(valid_input(), DEFAULT_ALPHA) == 2.0 + + // alpha scales only the negative side, and ELU(x) never goes below -alpha (in f32 + // ELU(-20) rounds to exactly -alpha) + test "forward_alpha_scales_negative_side" + given input = negative_input() + when result = forward(input, 0.5) + then @abs(result - 0.5 * forward(input, 1.0)) < 0.000001 and forward(-20.0, 0.5) >= -0.5 + + test "forward_batch_basic_case" + given input = negative_input() + when result = batch_at(0) + then result == forward(input, DEFAULT_ALPHA) and batch_at(1) == 0.0 and batch_at(2) == 2.0 + + // ELU'(-1) = exp(-1) = 0.3678794; ELU'(2) = 1 + test "derivative_basic_case" + given input = negative_input() + when result = derivative(input, DEFAULT_ALPHA) + then @abs(result - 0.3678794) < 0.000001 and derivative(valid_input(), DEFAULT_ALPHA) == 1.0 + + test "derivative_matches_finite_difference" + given slope = (forward(-1.0 + 0.001, DEFAULT_ALPHA) - forward(-1.0 - 0.001, DEFAULT_ALPHA)) / 0.002 + when result = derivative(-1.0, DEFAULT_ALPHA) + then @abs(result - slope) < 0.001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + invariant elu_constraint_0 + assert DEFAULT_ALPHA > 0.0 + + // name: elu_formula -- identity on the positive side + invariant elu_constraint_1 + assert forward(valid_input(), DEFAULT_ALPHA) == valid_input() + + // name: derivative -- 1 on the positive side + invariant elu_constraint_2 + assert derivative(valid_input(), DEFAULT_ALPHA) == 1.0 + + // "Clevert et al. (2016) - Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)": + // ELU is continuous at 0 + invariant elu_constraint_3 + assert forward(0.0, DEFAULT_ALPHA) == 0.0 diff --git a/apps/website/public/widgets/nn-elu/nn-elu.t27 b/apps/website/public/widgets/nn-elu/nn-elu.t27 new file mode 100644 index 0000000000..9d38c009ac --- /dev/null +++ b/apps/website/public/widgets/nn-elu/nn-elu.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-elu.t27 -- ELU: a negative side with a floor at -alpha +; Source of truth for public/widgets/nn-elu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-elu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/elu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 6 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -5 to 3 and sets alpha from 0.1 to 2. The curve is +; forward(x, alpha), the slope derivative(x, alpha), and the floor line is forward far to the left +; (x = -100). + +; WHAT IT DOES NOT CLAIM: the floor is read as forward(-100, alpha), which is -alpha to f32 +; precision, not the limit itself. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_elu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-elu"; +pub const TITLE : str = "ELU: a negative side with a floor"; +pub const DESCRIPTION : str = "Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies."; +pub const IMAGE_ALT : str = "ELU card at alpha 1, x = -3: the green curve runs along the diagonal for positive x and bends down toward the red dashed floor at -1 on the left; the dashed gold slope is 1 on the right and decays toward 0 on the left. Tiles read -0.9502, slope 0.0498, floor -1.0000 and the spec batch (-1, 0, 2) as -0.632 0.000 2.000."; +pub const HOOK : str = "ELU(-3) with alpha 1 is -0.9502, already 95% of the way to its floor of -1, and its slope there is still 0.0498, not 0."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/elu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 6 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -500; +pub const K_X_HI_C : i16 = 300; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -220; +pub const K_Y_HI_C : i16 = 300; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 3]; +pub const K_Y_TICKS : [6]i8 = [-2, -1, 0, 1, 2, 3]; +pub const K_ALPHA_LO_C : u8 = 10; +pub const K_ALPHA_HI_C : u8 = 200; +pub const K_ALPHA_STEP_C : u8 = 5; +pub const K_FAR_LEFT : u8 = 100; +pub const K_PRESET_X_C : [4]i16 = [-300, -300, 150, -100]; +pub const K_PRESET_ALPHA_C : [4]u8 = [100, 50, 100, 200]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["alpha 1, x = -3", "alpha 0.5, x = -3", "alpha 1, x = 1.5", "alpha 2, x = -1"]; +pub const SAY_ASK : str = "What if the negative side had a floor instead of a cliff?"; +pub const SAY_X : str = "input x"; +pub const SAY_ALPHA : str = "alpha"; +pub const SAY_F : str = "ELU(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_FLOOR : str = "floor"; +pub const SAY_PLOT_LABEL : str = "ELU of x, its slope and its floor from -5 to 3"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch -1 0 2"; +pub const SAY_NOTE : str = "ReLU throws the negative side away; ELU keeps a soft version of it, so a unit stuck below zero still moves. alpha is how deep the floor lies."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/elu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_floor_is_far_left { + assert K_FAR_LEFT == 100; + assert K_FAR_LEFT * 100 + K_X_LO_C > 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_ALPHA_C[3] == K_ALPHA_HI_C; + assert K_PRESET_ALPHA_C[1] >= K_ALPHA_LO_C; + assert K_Y_LO_C + 200 < 0; +} diff --git a/apps/website/public/widgets/nn-elu/tool.js b/apps/website/public/widgets/nn-elu/tool.js new file mode 100644 index 0000000000..dce2852071 --- /dev/null +++ b/apps/website/public/widgets/nn-elu/tool.js @@ -0,0 +1,38 @@ +// nn-elu/tool.js -- lesson 6 of neural-networks: a negative side with a floor. ELU is x above zero +// and alpha (e^x - 1) below, so it never falls under -alpha and its slope never quite dies. The +// curve, the slope and the floor (forward far to the left) are forward and derivative of +// gHashTag/t27 specs/ml/activation/elu_activation.t27, compiled to wasm (./logic.js). Words are SAY_ +// and numbers K_ constants of specs/widgets/nn-elu.t27. +import { batchAt, derivative, forward } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, svgEl, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -500)), X1 = centi(K('K_X_HI_C', 300)) +const FAR = -K('K_FAR_LEFT', 100) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, + { key: 'alpha', label: say('SAY_ALPHA'), min: centi(K('K_ALPHA_LO_C', 10)), max: centi(K('K_ALPHA_HI_C', 200)), step: centi(K('K_ALPHA_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi), alpha: K('K_PRESET_ALPHA_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_F'), COLORS[0]], [say('SAY_DF'), COLORS[1], true], [say('SAY_FLOOR'), COLORS[6], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: X0, x1: X1, y0: centi(K('K_Y_LO_C', -220)), y1: centi(K('K_Y_HI_C', 300)), xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_X') } + const p = plot(svg, o) + const floor = forward(FAR, s.alpha) + svg.append(svgEl('line', { x1: p.left, x2: 640 - p.right, y1: p.clampY(floor), y2: p.clampY(floor), stroke: COLORS[6], 'stroke-width': 2, 'stroke-dasharray': '8 6' })) + p.line(sample((x) => derivative(x, s.alpha), X0, X1, 320), COLORS[1], 2, { 'stroke-dasharray': '6 5' }) + p.line(sample((x) => forward(x, s.alpha), X0, X1), COLORS[0], 3.5) + cursor(svg, p, s.x, [[forward(s.x, s.alpha), COLORS[0]], [derivative(s.x, s.alpha), COLORS[1]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + stat.replaceChildren(tiles([ + { label: say('SAY_OUT'), value: fmt(forward(s.x, s.alpha), 4), tone: 0 }, + { label: say('SAY_GRAD'), value: fmt(derivative(s.x, s.alpha), 4), tone: 1 }, + { label: say('SAY_FLOOR'), value: fmt(floor, 4), tone: 6 }, + { label: say('SAY_BATCH'), value: [0, 1, 2].map((i) => fmt(batchAt(i), 3)).join(' '), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-embedding/card.png b/apps/website/public/widgets/nn-embedding/card.png new file mode 100644 index 0000000000000000000000000000000000000000..0f9ff780db884595d00f9b8ebad4908a774aa17d GIT binary patch literal 39510 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 Z6DZ{y4lJE}cvds~6aG-Y#$#vD{{ql|mdOAB literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-embedding/index.html b/apps/website/public/widgets/nn-embedding/index.html new file mode 100644 index 0000000000..3a0eb09bf6 --- /dev/null +++ b/apps/website/public/widgets/nn-embedding/index.html @@ -0,0 +1,47 @@ + + + + + + +Embeddings: how a word becomes a row of numbers · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Embeddings: how a word becomes a row of numbers

+

Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/embedding_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 8 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-embedding/logic.js b/apps/website/public/widgets/nn-embedding/logic.js new file mode 100644 index 0000000000..51b8d9ffe6 --- /dev/null +++ b/apps/website/public/widgets/nn-embedding/logic.js @@ -0,0 +1,36 @@ +// Generated by scripts/t27-logic.mjs from embedding_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: ee2625cfeb90bf9220fdf4a9d1010af3a2327bceafd4fd6341b08b4e1af54094 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-embedding/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABEQNgAAF/YAF/AX1gA39/fwF9AwUEAAECAgQFAXABAQEFAwEAEQYJAX8BQYCAwAALB0gFBm1lbW9yeQIAD3QyN192YWxpZF9pbnB1dAAAC3QyN19pbml0X2F0AAELdDI3X2dyYWRfYXQAAg10MjdfbG9va3VwX2F0AAMKrgQEBABBCAtuAgF/AX0jgICAgABBIGsiASSAgICAACABQsDFg/CD7s/Avn83AhggAULbi6zoq4u+yz43AhAgAUKuy5ny24KU2D43AgggAULzidT1q/6+nj43AgAgASAAQQJ0aioCACECIAFBIGokgICAgAAgAgvMAQICfwF9I4CAgIAAQTBrIgMkgICAgAAgA0EQakEIakIANwMAIANBIGpCADcDACADQShqQgA3AwAgA0IANwMQIAMgATYCDCADIAA2AghBcCEBIANBCGohBAJAA0AgAUUNASADQRBqIAQoAgBBA3RqIgAgACoCACABQZCAwIAAaioCAJI4AgAgACAAKgIEIAFBlIDAgABqKgIAkjgCBCAEQQRqIQQgAUEIaiEBDAALCyADQRBqIAJBAnRqKgIAIQUgA0EwaiSAgICAACAFC+kBAgJ/AX0jgICAgABBwABrIgMkgICAgABBACEEIANBMGpBCGpBACkCmIDAgAA3AwAgAyABNgIsIAMgADYCKCADQQApApCAwIAANwMwIANCgIDAj4SAgPzBADcCICADQoCAgI2EgIDUwQA3AhggA0KAgICJhICAmMEANwIQIANCgICAgICAgMA/NwIIIANBMGohAQJAA0AgBEEIRg0BIAEgA0EIaiADQShqIARqKAIAQQN0aikCADcCACAEQQRqIQQgAUEIaiEBDAALCyADQTBqIAJBAnRqKgIAIQUgA0HAAGokgICAgAAgBQsLKQEAQYCAwAALIAAAgD8AAABAAABAQAAAgEAAAIC/AACAvwAAgL8AAIC/"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function lookupAt(a, b, index) { + return W.t27_lookup_at(int(a, 0, 4294967295, "lookup_at.a"), int(b, 0, 4294967295, "lookup_at.b"), int(index, 0, 4294967295, "lookup_at.index")); +} +function gradAt(a, b, index) { + return W.t27_grad_at(int(a, 0, 4294967295, "grad_at.a"), int(b, 0, 4294967295, "grad_at.b"), int(index, 0, 4294967295, "grad_at.index")); +} +function initAt(index) { + return W.t27_init_at(int(index, 0, 4294967295, "init_at.index")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "init", "cfg"]); +export { + __NOT_LOWERED__, + gradAt, + initAt, + lookupAt, + validInput +}; diff --git a/apps/website/public/widgets/nn-embedding/logic.t27 b/apps/website/public/widgets/nn-embedding/logic.t27 new file mode 100644 index 0000000000..836fe230b7 --- /dev/null +++ b/apps/website/public/widgets/nn-embedding/logic.t27 @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Embeddings are learned parameters | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward only asserted its arguments and wrote nothing, the tests called +// undeclared `test_input_forward` / `test_input_init` and asserted +// `result != undefined`, and the invariants asserted `true`. forward now looks each +// token's row up in W (vocab_size x d_model, row-major), backward adds each +// gradient row back into the row it came from, and init fills W deterministically. + +module Embedding; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_D_MODEL : u32 = 64; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const EmbeddingConfig = struct { + vocab_size : u32, + d_model : u32, + }; + + pub const EmbeddingWeights = struct { + W : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // embeddings[t * d + j] = W[token_ids[t] * d + j]: one row of W per token + fn forward(token_ids: []const u32, weights: EmbeddingWeights, embeddings: []f32, config: EmbeddingConfig) -> void { + const d : usize = config.d_model; + var t : usize = 0; + while (t < token_ids.len) { + const row : usize = token_ids[t]; + var j : usize = 0; + while (j < d) { + embeddings[t * d + j] = weights.W[row * d + j]; + j = j + 1; + } + t = t + 1; + } + } + + // grad_W[token_ids[t]] += grad_embeddings[t]: a token seen twice collects both rows + fn backward(token_ids: []const u32, grad_embeddings: []const f32, grad_W: []f32, config: EmbeddingConfig) -> void { + const d : usize = config.d_model; + var t : usize = 0; + while (t < token_ids.len) { + const row : usize = token_ids[t]; + var j : usize = 0; + while (j < d) { + grad_W[row * d + j] = grad_W[row * d + j] + grad_embeddings[t * d + j]; + j = j + 1; + } + t = t + 1; + } + } + + // Deterministic init in [-0.5, 0.5) / sqrt(d_model): a fixed hash of (row, column), so + // two runs start from the same weights + fn init(weights: EmbeddingWeights, config: EmbeddingConfig) -> void { + const d : usize = config.d_model; + const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d))); + var k : usize = 0; + while (k < config.vocab_size * d) { + const h : u32 = @as(u32, @intCast((k * 2654435761) % 1000)); + weights.W[k] = (@as(f32, @floatFromInt(h)) / 1000.0 - 0.5) * scale; + k = k + 1; + } + } + + // vocab 4, d_model 2, W row v = (10 v, 10 v + 1) + fn cfg() -> EmbeddingConfig { + return EmbeddingConfig{ .vocab_size = 4, .d_model = 2 }; + } + + fn lookup_at(a: u32, b: u32, index: usize) -> f32 { + var w : [8]f32 = [0.0, 1.0, 10.0, 11.0, 20.0, 21.0, 30.0, 31.0]; + const ids : [2]u32 = [a, b]; + var out : [4]f32 = [-1.0] ** 4; + forward(&ids, EmbeddingWeights{ .W = &w }, &out, cfg()); + return out[index]; + } + + // grad_W[index] after backward of ids (a, b) with gradient rows (1, 2) and (3, 4) + fn grad_at(a: u32, b: u32, index: usize) -> f32 { + const ids : [2]u32 = [a, b]; + const grads : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var grad_w : [8]f32 = [0.0] ** 8; + backward(&ids, &grads, &grad_w, cfg()); + return grad_w[index]; + } + + fn init_at(index: usize) -> f32 { + var w : [8]f32 = [9.0] ** 8; + init(EmbeddingWeights{ .W = &w }, cfg()); + return w[index]; + } + + fn valid_input() -> u32 { + return cfg().vocab_size * cfg().d_model; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // ids (2, 0): rows (20, 21) then (0, 1) + test forward_basic_case + given first = lookup_at(2, 0, 0) + when last = lookup_at(2, 0, 3) + then first == 20.0 and lookup_at(2, 0, 1) == 21.0 and lookup_at(2, 0, 2) == 0.0 and last == 1.0 + + // Every weight is written, inside [-0.5, 0.5) / sqrt(2), and init is reproducible + test init_basic_case + given first = init_at(0) + when last = init_at(7) + then first != 9.0 and last != 9.0 and @abs(first) <= 0.36 and @abs(last) <= 0.36 and init_at(5) == init_at(5) and init_at(1) != init_at(2) + + // A token seen twice collects both gradient rows; an unseen row stays 0 + test backward_accumulates_repeated_tokens + given row1 = grad_at(1, 1, 2) + when unseen = grad_at(1, 1, 0) + then row1 == 4.0 and grad_at(1, 1, 3) == 6.0 and unseen == 0.0 and grad_at(1, 3, 6) == 3.0 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // vocab_size > 0 + invariant embedding_constraint_0 + assert cfg().vocab_size > 0 + + // d_model > 0 + invariant embedding_constraint_1 + assert cfg().d_model > 0 and DEFAULT_D_MODEL > 0 + + // W.size() == vocab_size * d_model + invariant embedding_constraint_2 + assert valid_input() == 8 + + // token_ids must be in [0, vocab_size): the last id reads the last row + invariant embedding_constraint_3 + assert lookup_at(3, 3, 1) == 31.0 + + // "Embedding dimension affects model capacity": each token gets d_model numbers + invariant embedding_constraint_4 + assert lookup_at(1, 2, 1) == 11.0 and lookup_at(1, 2, 2) == 20.0 + + // "Larger vocab requires larger d_model": the init scale shrinks as 1 / sqrt(d_model) + invariant embedding_constraint_5 + assert 1.0 / sqrt(@as(f32, 64.0)) < 1.0 / sqrt(@as(f32, 2.0)) + + // "Pre-trained embeddings transfer well": forward is a pure lookup, so loaded rows come out unchanged + invariant embedding_constraint_6 + assert lookup_at(0, 1, 0) == 0.0 and lookup_at(0, 1, 2) == 10.0 diff --git a/apps/website/public/widgets/nn-embedding/nn-embedding.t27 b/apps/website/public/widgets/nn-embedding/nn-embedding.t27 new file mode 100644 index 0000000000..309aaa6fd1 --- /dev/null +++ b/apps/website/public/widgets/nn-embedding/nn-embedding.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-embedding.t27 -- the embedding table: a word becomes a row of numbers +; Source of truth for public/widgets/nn-embedding/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-embedding/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/embedding_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 8 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks two tokens from four. The table is lookup_at(v, v, j) for every row +; v, the output lookup_at(a, b, i), and the gradient table grad_at(a, b, i) for the spec's gradient +; rows (1, 2) and (3, 4). + +; WHAT IT DOES NOT CLAIM: the table is the spec's 4 x 2 fixture (row v = 10 v, 10 v + 1); a real one +; has a row per word and hundreds of columns. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_embedding; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-embedding"; +pub const TITLE : str = "Embeddings: how a word becomes a row of numbers"; +pub const DESCRIPTION : str = "Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both."; +pub const IMAGE_ALT : str = "Embedding card: token 2 read twice from a 4 x 2 table whose rows are (0, 1), (10, 11), (20, 21), (30, 31). Row 2 is outlined and the others dimmed; the output is (20, 21) twice, and the gradient table is all zero except row 2, which holds 4 and 6."; +pub const HOOK : str = "A token is an index into a table, nothing more. Read token 2 twice and its row's gradient is (1 + 3, 2 + 4) = (4, 6); the other rows get 0."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/embedding_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 8 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_VOCAB : u8 = 4; +pub const K_WIDTH : u8 = 2; +pub const K_PRESET_A : [3]u8 = [2, 1, 0]; +pub const K_PRESET_B : [3]u8 = [2, 3, 2]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["The same token twice", "Tokens 1 and 3", "Tokens 0 and 2"]; +pub const SAY_ASK : str = "How does a word become numbers a network can use?"; +pub const SAY_TOKEN_NAMES : [4]str = ["token 0", "token 1", "token 2", "token 3"]; +pub const SAY_FIRST : str = "first token"; +pub const SAY_SECOND : str = "second token"; +pub const SAY_DIM : str = "dim"; +pub const SAY_TABLE_LABEL : str = "The embedding table: one row per token"; +pub const SAY_OUT_LABEL : str = "What the layer outputs"; +pub const SAY_GRAD_LABEL : str = "Where the gradient lands"; +pub const SAY_ROWS_TOUCHED : str = "rows read"; +pub const SAY_ONE_ROW : str = "one row, twice"; +pub const SAY_TWO_ROWS : str = "two rows"; +pub const SAY_VECTORS : str = "output"; +pub const SAY_GRAD_ROW : str = "gradient of {0}"; +pub const SAY_NOTE : str = "An embedding layer has no multiply at all: it copies rows. Learning changes only the rows it copied, which is why a rare word learns slowly."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/embedding_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_table_is_the_spec_fixture { + assert K_VOCAB == 4; + assert K_WIDTH == 2; + assert K_VOCAB * K_WIDTH == 8; +} + +test the_presets_name_real_tokens { + assert K_PRESET_A[0] == K_PRESET_B[0]; + assert K_PRESET_B[1] < K_VOCAB; + assert K_PRESET_A[1] != K_PRESET_B[1]; +} diff --git a/apps/website/public/widgets/nn-embedding/tool.js b/apps/website/public/widgets/nn-embedding/tool.js new file mode 100644 index 0000000000..937af8e3cc --- /dev/null +++ b/apps/website/public/widgets/nn-embedding/tool.js @@ -0,0 +1,37 @@ +// nn-embedding/tool.js -- lesson 8 of neural-networks: how a word becomes numbers. An embedding is a +// table with one row per token; looking a token up copies its row, and learning sends the gradient +// back only to the rows that were looked up. Every cell is lookup_at or grad_at of gHashTag/t27 +// specs/ml/layers/embedding_layer.t27, compiled to wasm (./logic.js): vocab 4, width 2. Words are +// SAY_ and numbers K_ constants of specs/widgets/nn-embedding.t27. +import { gradAt, lookupAt } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fill, fmt, heat, root, say, source, tiles, tone } from '../nn-kit.js' + +const V = K('K_VOCAB', 4), D = K('K_WIDTH', 2) +const tokens = W.SAY_TOKEN_NAMES ?? [] +const ctl = controls([ + { key: 'a', label: say('SAY_FIRST'), kind: 'choice', options: tokens }, + { key: 'b', label: say('SAY_SECOND'), kind: 'choice', options: tokens }, +], { names: W.SAY_PRESET_NAMES, values: { a: K('K_PRESET_A', []), b: K('K_PRESET_B', []) } }, draw) + +const table = canvas('nn-heat', say('SAY_TABLE_LABEL')) +const out = canvas('nn-heat', say('SAY_OUT_LABEL')) +const grad = canvas('nn-heat', say('SAY_GRAD_LABEL')) +const stat = el('div') +const cols = [...Array(D)].map((_, j) => `${say('SAY_DIM')} ${j}`) +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('p', { class: 'dk-label' }, say('SAY_TABLE_LABEL')), table, + el('div', { class: 'nn-two' }, el('div', {}, el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_GRAD_LABEL')), grad)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + // Row v of the table is what looking v up returns: lookup_at(v, v, j). + heat(table, { rows: V, cols: D, value: (r, c) => lookupAt(r, r, c), lo: 0, hi: 31, rowLabels: tokens, colLabels: cols, w: 300, cell: 104, fmt: (v) => fmt(v, 0), mark: (r) => (r === s.a || r === s.b ? 'on' : 'dim') }) + heat(out, { rows: 2, cols: D, value: (r, c) => lookupAt(s.a, s.b, r * D + c), lo: 0, hi: 31, rowLabels: [tokens[s.a], tokens[s.b]], colLabels: cols, w: 300, cell: 104, fmt: (v) => fmt(v, 0) }) + heat(grad, { rows: V, cols: D, value: (r, c) => gradAt(s.a, s.b, r * D + c), color: (v) => tone(v, 6), rowLabels: tokens, colLabels: cols, w: 300, cell: 104, fmt: (v) => fmt(v, 0), mark: (r) => (r === s.a || r === s.b ? 'on' : '') }) + stat.replaceChildren(tiles([ + { label: say('SAY_ROWS_TOUCHED'), value: s.a === s.b ? say('SAY_ONE_ROW') : say('SAY_TWO_ROWS'), tone: 1 }, + { label: say('SAY_VECTORS'), value: [0, 1, 2, 3].map((i) => fmt(lookupAt(s.a, s.b, i), 0)).join(' '), tone: 5 }, + { label: fill(say('SAY_GRAD_ROW'), tokens[s.a]), value: [0, 1].map((j) => fmt(gradAt(s.a, s.b, s.a * D + j), 0)).join(', '), tone: 0 }, + { label: fill(say('SAY_GRAD_ROW'), tokens[s.b]), value: [0, 1].map((j) => fmt(gradAt(s.a, s.b, s.b * D + j), 0)).join(', '), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-encoder/card.png b/apps/website/public/widgets/nn-encoder/card.png new file mode 100644 index 0000000000000000000000000000000000000000..87c2017d279d4eaee1da80ac43e7ed4782d94e9e GIT binary patch literal 44025 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 + + + + + +An encoder block: what one transformer layer does · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

An encoder block: what one transformer layer does

+

Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/transformer/encoder_block.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 26 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-encoder/logic.js b/apps/website/public/widgets/nn-encoder/logic.js new file mode 100644 index 0000000000..7264e6e8d8 --- /dev/null +++ b/apps/website/public/widgets/nn-encoder/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from encoder_block.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: e21519a3f7912ca70d35919cc1f9d2927b746f8e545c741e3772c1eb7e06561a +// Imported by scripts/widget-logic.mjs for public/widgets/nn-encoder/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function attentionAt(which, index) { + return W.t27_attention_at(int(which, 0, 255, "attention_at.which"), int(index, 0, 4294967295, "attention_at.index")); +} +function tieAttention(index) { + return W.t27_tie_attention(int(index, 0, 4294967295, "tie_attention.index")); +} +function blockAt(preNorm, which, index) { + return W.t27_block_at(preNorm ? 1 : 0, int(which, 0, 255, "block_at.which"), int(index, 0, 4294967295, "block_at.index")); +} +function ffnAt(index) { + return W.t27_ffn_at(int(index, 0, 4294967295, "ffn_at.index")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["multi_head_attention", "feed_forward", "layer_norm", "forward", "cfg", "fixture_input", "ffn_fill"]); +export { + __NOT_LOWERED__, + attentionAt, + blockAt, + ffnAt, + tieAttention, + validInput +}; diff --git a/apps/website/public/widgets/nn-encoder/logic.t27 b/apps/website/public/widgets/nn-encoder/logic.t27 new file mode 100644 index 0000000000..1ced0caac4 --- /dev/null +++ b/apps/website/public/widgets/nn-encoder/logic.t27 @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Standard Transformer encoder block with residual connections | φ² + 1/φ² = 3 | TRINITY + +// #8980: attention and the FFN returned their input ("in real implementation +// ..."), forward skipped both residuals, and the tests asked only for a non-empty +// output from undeclared `default_input()`. The block now computes the Transformer +// encoder layer over a seq x d_model input. Attention is multi-head scaled +// dot-product, softmax(q k^T / sqrt(d_head)) v per head, with identity projections. +// Then come the position-wise FFN and two residual + layer-norm steps: post-norm +// LN(x + f(x)) by default, pre-norm x + f(LN(x)) when use_pre_norm is set. + +module EncoderBlock; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_D_MODEL : u32 = 512; + const DEFAULT_N_HEADS : u32 = 8; + const DEFAULT_D_FF : u32 = 2048; + const DEFAULT_DROPOUT : f32 = 0.1; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const EncoderBlockConfig = struct { + d_model : u32, + n_heads : u32, + d_ff : u32, + dropout : f32, + use_pre_norm : bool, + }; + + pub const FFNWeights = struct { + w1 : []const f32, + b1 : []const f32, + w2 : []const f32, + b2 : []const f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // q, k, v and out are seq x d_model; attn_weights is n_heads x seq x seq. Head h uses + // columns h * d_head .. (h + 1) * d_head. + fn multi_head_attention(query: []const f32, key: []const f32, value: []const f32, seq: usize, n_heads: u32, d_model: u32, out: []f32, attn_weights: []f32) -> void { + const d_head : usize = d_model / n_heads; + const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d_head))); + var h : usize = 0; + while (h < n_heads) { + var i : usize = 0; + while (i < seq) { + const row = attn_weights[(h * seq + i) * seq .. (h * seq + i + 1) * seq]; + var max_s : f32 = -1.0e30; + var j : usize = 0; + while (j < seq) { + var dot : f32 = 0.0; + var c : usize = 0; + while (c < d_head) { + dot = dot + query[i * d_model + h * d_head + c] * key[j * d_model + h * d_head + c]; + c = c + 1; + } + row[j] = dot * scale; + max_s = @max(max_s, row[j]); + j = j + 1; + } + var sum : f32 = 0.0; + j = 0; + while (j < seq) { + row[j] = exp(row[j] - max_s); + sum = sum + row[j]; + j = j + 1; + } + var c : usize = 0; + while (c < d_head) { + var acc : f32 = 0.0; + j = 0; + while (j < seq) { + acc = acc + row[j] / sum * value[j * d_model + h * d_head + c]; + j = j + 1; + } + out[i * d_model + h * d_head + c] = acc; + c = c + 1; + } + j = 0; + while (j < seq) { + row[j] = row[j] / sum; + j = j + 1; + } + i = i + 1; + } + h = h + 1; + } + } + + // out = W2 relu(W1 x + b1) + b2 for one row; hidden is d_ff floats of scratch. + // Dropout is the identity at inference, which is what this block computes. + fn feed_forward(input: []const f32, weights: FFNWeights, d_model: u32, d_ff: u32, hidden: []f32, out: []f32) -> void { + var f : usize = 0; + while (f < d_ff) { + var z : f32 = weights.b1[f]; + var j : usize = 0; + while (j < d_model) { + z = z + weights.w1[f * d_model + j] * input[j]; + j = j + 1; + } + hidden[f] = @max(z, 0.0); + f = f + 1; + } + var o : usize = 0; + while (o < d_model) { + var y : f32 = weights.b2[o]; + f = 0; + while (f < d_ff) { + y = y + weights.w2[o * d_ff + f] * hidden[f]; + f = f + 1; + } + out[o] = y; + o = o + 1; + } + } + + // (x - mean) / sqrt(var + 1e-5), no learned scale or shift + fn layer_norm(x: []const f32, out: []f32) -> void { + var mean : f32 = 0.0; + var k : usize = 0; + while (k < x.len) { + mean = mean + x[k]; + k = k + 1; + } + mean = mean / @as(f32, @floatFromInt(x.len)); + var variance : f32 = 0.0; + k = 0; + while (k < x.len) { + variance = variance + (x[k] - mean) * (x[k] - mean); + k = k + 1; + } + variance = variance / @as(f32, @floatFromInt(x.len)); + k = 0; + while (k < x.len) { + out[k] = (x[k] - mean) / sqrt(variance + 0.00001); + k = k + 1; + } + } + + // input and out are seq x d_model. scratch needs 3 seq d_model + n_heads seq^2 + d_ff + d_model floats. + fn forward(input: []const f32, seq: usize, ffn: FFNWeights, config: EncoderBlockConfig, out: []f32, scratch: []f32) -> void { + const n : usize = seq * config.d_model; + const d : usize = config.d_model; + const normed = scratch[0..n]; + const attn = scratch[n .. 2 * n]; + const mid = scratch[2 * n .. 3 * n]; + const weights = scratch[3 * n .. 3 * n + config.n_heads * seq * seq]; + const rest = 3 * n + config.n_heads * seq * seq; + const hidden = scratch[rest .. rest + config.d_ff]; + const row = scratch[rest + config.d_ff .. rest + config.d_ff + d]; + var t : usize = 0; + if (config.use_pre_norm) { + while (t < seq) { + layer_norm(input[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]); + t = t + 1; + } + multi_head_attention(normed, normed, normed, seq, config.n_heads, config.d_model, attn, weights); + var k : usize = 0; + while (k < n) { + mid[k] = input[k] + attn[k]; + k = k + 1; + } + t = 0; + while (t < seq) { + layer_norm(mid[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]); + feed_forward(normed[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row); + var c : usize = 0; + while (c < d) { + out[t * d + c] = mid[t * d + c] + row[c]; + c = c + 1; + } + t = t + 1; + } + return; + } + multi_head_attention(input, input, input, seq, config.n_heads, config.d_model, attn, weights); + var k : usize = 0; + while (k < n) { + normed[k] = input[k] + attn[k]; + k = k + 1; + } + t = 0; + while (t < seq) { + layer_norm(normed[t * d .. (t + 1) * d], mid[t * d .. (t + 1) * d]); + feed_forward(mid[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row); + var c : usize = 0; + while (c < d) { + normed[t * d + c] = mid[t * d + c] + row[c]; + c = c + 1; + } + layer_norm(normed[t * d .. (t + 1) * d], out[t * d .. (t + 1) * d]); + t = t + 1; + } + } + + // The fixture: seq 3, d_model 4, 2 heads, d_ff 8 + fn cfg(pre_norm: bool) -> EncoderBlockConfig { + return EncoderBlockConfig{ .d_model = 4, .n_heads = 2, .d_ff = 8, .dropout = DEFAULT_DROPOUT, .use_pre_norm = pre_norm }; + } + + fn fixture_input(x: []f32) -> void { + const v : [12]f32 = [1.0, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 2.0, 1.0, 1.0, 0.0, 0.0]; + var k : usize = 0; + while (k < 12) { + x[k] = v[k]; + k = k + 1; + } + } + + // which: 0 = out[index], 1 = attn_weights[index] of self-attention on the fixture + fn attention_at(which: u8, index: usize) -> f32 { + var x : [12]f32 = undefined; + fixture_input(&x); + var out : [12]f32 = [9.0] ** 12; + var weights : [18]f32 = [9.0] ** 18; + multi_head_attention(&x, &x, &x, 3, 2, 4, &out, &weights); + if (which == 0) { + return out[index]; + } + return weights[index]; + } + + // Two keys equal: attention splits evenly and returns the mean of the values + fn tie_attention(index: usize) -> f32 { + const q : [2]f32 = [1.0, 1.0]; + const k : [2]f32 = [2.0, 2.0]; + const v : [2]f32 = [4.0, 10.0]; + var out : [2]f32 = [0.0] ** 2; + var weights : [4]f32 = [0.0] ** 4; + multi_head_attention(&q, &k, &v, 2, 1, 1, &out, &weights); + return out[index]; + } + + fn ffn_fill(w1: []f32, b1: []f32, w2: []f32, b2: []f32) -> void { + var k : usize = 0; + while (k < 32) { + w1[k] = @as(f32, @floatFromInt((k * 5 + 1) % 9)) / 8.0 - 0.5; + w2[k] = @as(f32, @floatFromInt((k * 7 + 2) % 9)) / 8.0 - 0.5; + k = k + 1; + } + k = 0; + while (k < 8) { + b1[k] = 0.1; + k = k + 1; + } + k = 0; + while (k < 4) { + b2[k] = -0.1; + k = k + 1; + } + } + + // which: 0 = out[index]; 1 = mean of row `index`; 2 = variance of row `index` + fn block_at(pre_norm: bool, which: u8, index: usize) -> f32 { + var x : [12]f32 = undefined; + fixture_input(&x); + var w1 : [32]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [32]f32 = undefined; + var b2 : [4]f32 = undefined; + ffn_fill(&w1, &b1, &w2, &b2); + var out : [12]f32 = [9.0] ** 12; + var scratch : [3 * 12 + 18 + 8 + 4]f32 = undefined; + forward(&x, 3, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, cfg(pre_norm), &out, &scratch); + if (which == 0) { + return out[index]; + } + var mean : f32 = 0.0; + var c : usize = 0; + while (c < 4) { + mean = mean + out[index * 4 + c] / 4.0; + c = c + 1; + } + if (which == 1) { + return mean; + } + var variance : f32 = 0.0; + c = 0; + while (c < 4) { + variance = variance + (out[index * 4 + c] - mean) * (out[index * 4 + c] - mean) / 4.0; + c = c + 1; + } + return variance; + } + + // FFN on row (1, 0, 0.5, -1) of the fixture weights; out[index] + fn ffn_at(index: usize) -> f32 { + var w1 : [32]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [32]f32 = undefined; + var b2 : [4]f32 = undefined; + ffn_fill(&w1, &b1, &w2, &b2); + const x : [4]f32 = [1.0, 0.0, 0.5, -1.0]; + var hidden : [8]f32 = undefined; + var out : [4]f32 = [9.0] ** 4; + feed_forward(&x, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, 4, 8, &hidden, &out); + return out[index]; + } + + fn valid_input() -> u32 { + return DEFAULT_D_MODEL / DEFAULT_N_HEADS; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // Every attention row is a distribution; equal keys give the mean of the values + test multi_head_attention_basic_case + given row_sum = attention_at(1, 0) + attention_at(1, 1) + attention_at(1, 2) + when tied = tie_attention(0) + then @abs(row_sum - 1.0) < 0.000001 and tied == 7.0 and tie_attention(1) == 7.0 and attention_at(0, 0) != 9.0 + + // Heads are independent: head 1's weights (rows 9..17) differ from head 0's + test multi_head_attention_heads_differ + given w0 = attention_at(1, 1) + when w1 = attention_at(1, 10) + then w0 != w1 and w0 > 0.0 and w1 > 0.0 + + // W2 relu(W1 x + b1) + b2 on the fixture row, worked by hand: (0.4125, ..., -0.178125) + test feed_forward_basic_case + given y0 = ffn_at(0) + when y3 = ffn_at(3) + then @abs(y0 - 0.4125) < 0.000001 and @abs(y3 + 0.178125) < 0.000001 and @abs(ffn_at(2) + 0.928125) < 0.000001 + + // Post-norm: every output row has mean 0 and variance 1 + test forward_basic_case + given mean1 = block_at(false, 1, 1) + when var1 = block_at(false, 2, 1) + then @abs(mean1) < 0.00001 and @abs(var1 - 1.0) < 0.001 and @abs(block_at(false, 1, 2)) < 0.00001 + + // Pre-norm keeps the residual stream un-normalised, so it differs from post-norm + test forward_pre_norm_differs + given pre = block_at(true, 0, 0) + when post = block_at(false, 0, 0) + then pre != post and pre == pre + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // d_model % n_heads == 0 + invariant encoder_block_constraint_0 + assert DEFAULT_D_MODEL % DEFAULT_N_HEADS == 0 and cfg(false).d_model % cfg(false).n_heads == 0 + + // d_ff >= d_model + invariant encoder_block_constraint_1 + assert DEFAULT_D_FF >= DEFAULT_D_MODEL and cfg(false).d_ff >= cfg(false).d_model + + // name: encoder_block -- each head gets d_model / n_heads columns + invariant encoder_block_constraint_2 + assert valid_input() == 64 + + // "Vaswani et al. (2017) - Attention Is All You Need": dropout is a probability + invariant encoder_block_constraint_3 + assert DEFAULT_DROPOUT >= 0.0 and DEFAULT_DROPOUT < 1.0 + + // "Baevski et al. (2020) - Revisiting the Self-Attention": both norm placements are offered + invariant encoder_block_constraint_4 + assert cfg(true).use_pre_norm and !cfg(false).use_pre_norm diff --git a/apps/website/public/widgets/nn-encoder/nn-encoder.t27 b/apps/website/public/widgets/nn-encoder/nn-encoder.t27 new file mode 100644 index 0000000000..66df55b1cc --- /dev/null +++ b/apps/website/public/widgets/nn-encoder/nn-encoder.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-encoder.t27 -- a transformer encoder block, post-norm and pre-norm +; Source of truth for public/widgets/nn-encoder/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-encoder/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/transformer/encoder_block.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 26 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles post-norm and pre-norm. The output grid is block_at(pre, 0, i), +; the row means and variances block_at(pre, 1 or 2, row), and the attention grids attention_at(1, +; i): 3 positions, d_model 4, 2 heads, d_ff 8, the spec's weights. + +; WHAT IT DOES NOT CLAIM: one block with the spec's fixed weights, not a trained model; a +; transformer stacks dozens. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_encoder; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-encoder"; +pub const TITLE : str = "An encoder block: what one transformer layer does"; +pub const DESCRIPTION : str = "Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not."; +pub const IMAGE_ALT : str = "Encoder card, post-norm: a 3 x 4 output grid in pink and green, every row centred on 0. Tiles read row means 0.000 0.000 0.000 and variances 1.000 1.000 1.000. Below, two 3 x 3 attention grids of the block, head 0 row 0 reading 0.401 0.198 0.401."; +pub const HOOK : str = "Post-norm rows come out at mean 0 and variance 1.000; pre-norm rows at variances 2.73, 3.33 and 0.96, because its last step is a residual add."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/transformer/encoder_block.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 26 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SEQ : u8 = 3; +pub const K_D_MODEL : u8 = 4; +pub const K_HEADS : u8 = 2; +pub const K_PRESET_PRE : [2]u8 = [0, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [2]str = ["Post-norm", "Pre-norm"]; +pub const SAY_ASK : str = "What does one layer of a transformer actually do to its input?"; +pub const SAY_PRE_NORM : str = "pre-norm"; +pub const SAY_HEAD : str = "head"; +pub const SAY_POS : str = "pos"; +pub const SAY_DIM : str = "dim"; +pub const SAY_OUT_LABEL : str = "The block's output: 3 positions x 4 dimensions"; +pub const SAY_ATT_LABEL : str = "The block's self-attention weights"; +pub const SAY_MEANS : str = "row means"; +pub const SAY_VARS : str = "row variances"; +pub const SAY_ORDER : str = "order"; +pub const SAY_ORDER_POST : str = "attend, add, norm, FFN, add, norm"; +pub const SAY_ORDER_PRE : str = "norm, attend, add, norm, FFN, add"; +pub const SAY_ATT_ROW : str = "head 0, pos 0 reads"; +pub const SAY_NOTE : str = "The residual adds keep the input flowing through, so a deep stack can train; the norms keep the numbers in range. Where the norm sits decides what comes out."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/transformer/encoder_block.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test two_heads_split_the_model { + assert K_HEADS * 2 == K_D_MODEL; + assert K_SEQ == 3; +} + +test both_orders_are_offered { + assert K_PRESET_PRE[0] == 0; + assert K_PRESET_PRE[1] == 1; +} diff --git a/apps/website/public/widgets/nn-encoder/tool.js b/apps/website/public/widgets/nn-encoder/tool.js new file mode 100644 index 0000000000..556681f1cd --- /dev/null +++ b/apps/website/public/widgets/nn-encoder/tool.js @@ -0,0 +1,34 @@ +// nn-encoder/tool.js -- lesson 26 of neural-networks: what one transformer block does. Self-attention +// mixes the positions, a residual adds the input back, a two-layer feed-forward net works on each +// position, and layer norm keeps every row at mean 0 and variance 1; pre-norm moves the norms in +// front of each sublayer. Every value is block_at and attention_at of gHashTag/t27 +// specs/ml/transformer/encoder_block.t27, compiled to wasm (./logic.js): 3 positions, d_model 4, 2 +// heads, d_ff 8, the spec's own weights. Words are SAY_ and numbers K_ constants of specs/widgets/nn-encoder.t27. +import { attentionAt, blockAt } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, heatTone, root, say, source, tiles, tone } from '../nn-kit.js' + +const N = K('K_SEQ', 3), D = K('K_D_MODEL', 4), H = K('K_HEADS', 2) +const ctl = controls([ + { key: 'pre', label: say('SAY_PRE_NORM'), kind: 'toggle' }, +], { names: W.SAY_PRESET_NAMES, values: { pre: K('K_PRESET_PRE', []) } }, draw) + +const out = canvas('nn-heat', say('SAY_OUT_LABEL')) +const heads = [...Array(H)].map((_, h) => canvas('nn-heat', `${say('SAY_HEAD')} ${h}`)) +const stat = el('div') +const pos = [...Array(N)].map((_, i) => `${say('SAY_POS')} ${i}`) +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out, stat, + el('p', { class: 'dk-label' }, say('SAY_ATT_LABEL')), el('div', { class: 'nn-two' }, ...heads.map((svg, h) => el('div', {}, el('p', { class: 'nn-cap' }, `${say('SAY_HEAD')} ${h}`), svg))), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const pre = !!s.pre + heat(out, { rows: N, cols: D, value: (i, k) => blockAt(pre, 0, i * D + k), color: (v) => tone(v, 2), rowLabels: pos, colLabels: [...Array(D)].map((_, k) => `${say('SAY_DIM')} ${k}`), labelWidth: 70, w: 640, cell: 110, fmt: (v) => fmt(v, 3) }) + heads.forEach((svg, h) => heat(svg, { rows: N, cols: N, value: (i, j) => attentionAt(1, (h * N + i) * N + j), color: (v) => heatTone(v), rowLabels: pos, colLabels: pos, labelWidth: 70, w: 400, cell: 100, fmt: (v) => fmt(v, 3) })) + stat.replaceChildren(tiles([ + { label: say('SAY_MEANS'), value: [0, 1, 2].map((i) => fmt(blockAt(pre, 1, i), 3)).join(' '), tone: 0 }, + { label: say('SAY_VARS'), value: [0, 1, 2].map((i) => fmt(blockAt(pre, 2, i), 3)).join(' '), tone: 1 }, + { label: say('SAY_ORDER'), value: pre ? say('SAY_ORDER_PRE') : say('SAY_ORDER_POST'), tone: 2 }, + { label: say('SAY_ATT_ROW'), value: [0, 1, 2].map((j) => fmt(attentionAt(1, j), 3)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-gelu/card.png b/apps/website/public/widgets/nn-gelu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..e852eb5e716e939fd3766c0af47376bf2153b7d2 GIT binary patch literal 51583 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 Ks95m3_x}O*xr(3w literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-gelu/index.html b/apps/website/public/widgets/nn-gelu/index.html new file mode 100644 index 0000000000..1ba7192bc6 --- /dev/null +++ b/apps/website/public/widgets/nn-gelu/index.html @@ -0,0 +1,47 @@ + + + + + + +GELU: why transformers bend a little below zero · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

GELU: why transformers bend a little below zero

+

Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/gelu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 4 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-gelu/logic.js b/apps/website/public/widgets/nn-gelu/logic.js new file mode 100644 index 0000000000..09313001c9 --- /dev/null +++ b/apps/website/public/widgets/nn-gelu/logic.js @@ -0,0 +1,39 @@ +// Generated by scripts/t27-logic.mjs from gelu_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: c17aac3c9fafca2b4b81781946ad2933b51b66dda7b62b0b79347f5cba9c8df8 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-gelu/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function erf(x) { + return W.t27_erf(x); +} +function geluOne(x, approximate) { + return W.t27_gelu_one(x, approximate ? 1 : 0); +} +function geluGradOne(x, approximate) { + return W.t27_gelu_grad_one(x, approximate ? 1 : 0); +} +function forwardAt(x, approximate) { + return W.t27_forward_at(x, approximate ? 1 : 0); +} +function backwardAt(x, approximate) { + return W.t27_backward_at(x, approximate ? 1 : 0); +} +function productOf(a, b) { + return W.t27_product_of(a, b); +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "config_of"]); +export { + __NOT_LOWERED__, + backwardAt, + erf, + forwardAt, + geluGradOne, + geluOne, + productOf +}; diff --git a/apps/website/public/widgets/nn-gelu/logic.t27 b/apps/website/public/widgets/nn-gelu/logic.t27 new file mode 100644 index 0000000000..4c2b4a0e53 --- /dev/null +++ b/apps/website/public/widgets/nn-gelu/logic.t27 @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Based on cumulative distribution function | φ² + 1/φ² = 3 | TRINITY + +// #8980: Zig has neither `@tanh` nor `@erf`, so this never compiled. erf is now +// a function of this spec (Abramowitz-Stegun 7.1.26, |error| < 1.5e-7), and the +// exact derivative divides the normal density by sqrt(2 pi), not sqrt(2) (the +// slip was invisible at x = 0, the only point the tests checked). + +module Gelu; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const SQRT_2_OVER_PI : f32 = 0.7978845608; + const SQRT_PI_OVER_2 : f32 = 1.2533141373; + const SQRT_2 : f32 = 1.4142135624; + const SQRT_2_PI : f32 = 2.5066282746; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const GELUConfig = struct { + approximate : bool, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // erf(x), Abramowitz-Stegun 7.1.26: max absolute error 1.5e-7 + fn erf(x: f32) -> f32 { + if (x < 0.0) { + return -erf(-x); + } + const t = 1.0 / (1.0 + 0.3275911 * x); + const poly = t * (0.254829592 + t * (-0.284496736 + t * (1.421413741 + t * (-1.453152027 + t * 1.061405429)))); + return 1.0 - poly * exp(-x * x); + } + + // One element. approximate: 0.5 x (1 + tanh(sqrt(2/pi) (x + 0.044715 x^3))); + // exact: 0.5 x (1 + erf(x / sqrt(2))) = x Phi(x) + fn gelu_one(x: f32, approximate: bool) -> f32 { + if (approximate) { + const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x); + return 0.5 * x * (1.0 + tanh(inner)); + } + return 0.5 * x * (1.0 + erf(x / SQRT_2)); + } + + // d/dx of gelu_one + fn gelu_grad_one(x: f32, approximate: bool) -> f32 { + if (approximate) { + const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x); + const tanh_val = tanh(inner); + const sech_sq = 1.0 - tanh_val * tanh_val; + return 0.5 * (1.0 + tanh_val) + 0.5 * x * sech_sq * SQRT_2_OVER_PI * (1.0 + 3.0 * 0.044715 * x * x); + } + // Phi(x) + x phi(x), phi(x) = exp(-x^2 / 2) / sqrt(2 pi) + const cdf = 0.5 * (1.0 + erf(x / SQRT_2)); + const pdf = exp(-0.5 * x * x) / SQRT_2_PI; + return cdf + x * pdf; + } + + fn forward(input: []const f32, output: []f32, config: GELUConfig) -> void { + var i : usize = 0; + while (i < input.len) { + output[i] = gelu_one(input[i], config.approximate); + i = i + 1; + } + } + + fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: GELUConfig) -> void { + var i : usize = 0; + while (i < input.len) { + grad_input[i] = grad_output[i] * gelu_grad_one(input[i], config.approximate); + i = i + 1; + } + } + + // forward / backward over a one-element slice, for the tests + fn forward_at(x: f32, approximate: bool) -> f32 { + const input : [1]f32 = [x]; + var output : [1]f32 = [0.0]; + forward(&input, &output, GELUConfig{ .approximate = approximate }); + return output[0]; + } + + fn backward_at(x: f32, approximate: bool) -> f32 { + const grad_output : [1]f32 = [1.0]; + const input : [1]f32 = [x]; + var grad_input : [1]f32 = [0.0]; + backward(&grad_output, &input, &grad_input, GELUConfig{ .approximate = approximate }); + return grad_input[0]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // The product goes through a function so the check runs, not only folds at compile time. + fn product_of(a: f32, b: f32) -> f32 { + return a * b; + } + + fn config_of(approximate: bool) -> GELUConfig { + return GELUConfig{ .approximate = approximate }; + } + + test gelu_sqrt_constants_are_reciprocals + given product = product_of(SQRT_2_OVER_PI, SQRT_PI_OVER_2) + then @abs(product - 1.0) < 0.0000005 + + test gelu_sqrt_2_over_pi_squares_to_2_over_pi + given squared = product_of(SQRT_2_OVER_PI, SQRT_2_OVER_PI) + then @abs(squared - 0.63661977) < 0.0000003 + + test gelu_config_records_the_approximation_choice + given exact = config_of(false) + when approx = config_of(true) + then !exact.approximate and approx.approximate + + // erf(0) = 0, erf(1) = 0.8427008, erf(-1) = -erf(1) + test gelu_erf_known_values + given at_one = erf(1.0) + when at_zero = erf(0.0) + then @abs(at_zero) < 0.0000002 and @abs(at_one - 0.8427008) < 0.0000003 and erf(-1.0) == -at_one + + test gelu_forward_zero_input + given exact = forward_at(0.0, false) + when approx = forward_at(0.0, true) + then exact == 0.0 and approx == 0.0 + + test gelu_backward_zero_input_derivative + given exact = backward_at(0.0, false) + when approx = backward_at(0.0, true) + then @abs(exact - 0.5) < 0.0000002 and approx == 0.5 + + test gelu_forward_monotonic_positive_tail + given small = forward_at(1.0, true) + when large = forward_at(2.0, true) + then small < large + + // With the cubic term, approximate GELU(1) = 0.8411920; exact GELU(1) = Phi(1) = 0.8413447. + // Without it, 0.5 (1 + tanh(0.7978846)) = 0.8296438 -- so this pins the term. + test gelu_tanh_cubic_coefficient + given approx = forward_at(1.0, true) + when exact = forward_at(1.0, false) + then @abs(approx - 0.8411920) < 0.000001 and @abs(exact - 0.8413447) < 0.000001 + + test gelu_backward_exact_derivative_at_zero + given result = backward_at(0.0, false) + then @abs(result - 0.5) < 0.0000002 + + test gelu_forward_approx_derivative_at_zero + given result = backward_at(0.0, true) + then result == 0.5 + + // The derivative at x = 1 is where the old sqrt(2) slip showed: 1.0833155 exact + test gelu_backward_matches_finite_difference + given exact_slope = (forward_at(1.001, false) - forward_at(0.999, false)) / 0.002 + when approx_slope = (forward_at(1.001, true) - forward_at(0.999, true)) / 0.002 + then @abs(backward_at(1.0, false) - exact_slope) < 0.002 and @abs(backward_at(1.0, true) - approx_slope) < 0.002 and @abs(backward_at(1.0, false) - 1.0833155) < 0.000002 diff --git a/apps/website/public/widgets/nn-gelu/nn-gelu.t27 b/apps/website/public/widgets/nn-gelu/nn-gelu.t27 new file mode 100644 index 0000000000..7a202a415b --- /dev/null +++ b/apps/website/public/widgets/nn-gelu/nn-gelu.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-gelu.t27 -- GELU, exact and tanh form: the bend transformers use +; Source of truth for public/widgets/nn-gelu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-gelu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/gelu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 4 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 3. The exact curve is forward_at(x, false) through the +; spec's erf, the dashed curve forward_at(x, true), the tanh form, and the dotted curve backward_at, +; the slope. + +; WHAT IT DOES NOT CLAIM: the erf of the spec is the Abramowitz-Stegun 7.1.26 fit, good to 1.5e-7, +; so the exact curve is exact to that. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_gelu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-gelu"; +pub const TITLE : str = "GELU: why transformers bend a little below zero"; +pub const DESCRIPTION : str = "Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form."; +pub const IMAGE_ALT : str = "GELU card at x = -0.75: the thick green exact curve and the dashed pink tanh form lie on top of each other from -4 to 3, dipping just under zero near -0.75; the dotted cyan slope crosses zero there. Tiles read exact -0.16997, tanh form -0.17004 and slopes 0.0008."; +pub const HOOK : str = "GELU(-0.75) = -0.16997 exactly and -0.17004 by the tanh form. A smooth ReLU with a small dip, used in BERT and GPT."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/gelu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 4 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 300; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -50; +pub const K_Y_HI_C : i16 = 300; +pub const K_X_TICKS : [8]i8 = [-4, -3, -2, -1, 0, 1, 2, 3]; +pub const K_Y_TICKS_C : [4]i16 = [0, 100, 200, 300]; +pub const K_PRESET_X_C : [4]i16 = [-75, 150, -300, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["The dip, x = -0.75", "x = 1.5", "Far left, x = -3", "x = 0"]; +pub const SAY_ASK : str = "Why do transformers use a curve that bends a little below zero?"; +pub const SAY_X : str = "input x"; +pub const SAY_EXACT : str = "GELU, exact"; +pub const SAY_TANH : str = "GELU, tanh form"; +pub const SAY_DF : str = "slope"; +pub const SAY_DF_TANH : str = "slope, tanh form"; +pub const SAY_PLOT_LABEL : str = "GELU of x, exact and tanh form, and its slope from -4 to 3"; +pub const SAY_NOTE : str = "GELU(x) = x Phi(x): a positive input mostly passes, a large negative one mostly vanishes, and in between the curve dips. Unlike ReLU its slope is smooth everywhere."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/gelu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_dip_is_in_range { + assert K_PRESET_X_C[0] < 0; + assert K_PRESET_X_C[0] > K_X_LO_C; + assert K_Y_LO_C < 0; +} + +test the_window_is_wider_on_the_left { + assert K_X_LO_C + 400 == 0; + assert K_X_HI_C == 300; + assert K_X_TICKS[0] * 100 == K_X_LO_C; +} diff --git a/apps/website/public/widgets/nn-gelu/tool.js b/apps/website/public/widgets/nn-gelu/tool.js new file mode 100644 index 0000000000..426667d5ac --- /dev/null +++ b/apps/website/public/widgets/nn-gelu/tool.js @@ -0,0 +1,35 @@ +// nn-gelu/tool.js -- lesson 4 of neural-networks: why transformers bend below zero. GELU weighs x +// by the chance a standard normal is below it, so it dips a little under zero before it rises. The +// exact form (through erf), the tanh form and the slope are forward_at and backward_at of +// gHashTag/t27 specs/ml/activation/gelu_activation.t27, compiled to wasm (./logic.js). Words are SAY_ +// and numbers K_ constants of specs/widgets/nn-gelu.t27. +import { backwardAt, forwardAt } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -400)), X1 = centi(K('K_X_HI_C', 300)) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_EXACT'), COLORS[0]], [say('SAY_TANH'), COLORS[3], true], [say('SAY_DF'), COLORS[2], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: X0, x1: X1, y0: centi(K('K_Y_LO_C', -50)), y1: centi(K('K_Y_HI_C', 300)), xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS_C', []).map(centi), xlabel: say('SAY_X') } + const p = plot(svg, o) + p.line(sample((x) => backwardAt(x, false), X0, X1), COLORS[2], 1.5, { 'stroke-dasharray': '3 4' }) + p.line(sample((x) => forwardAt(x, false), X0, X1), COLORS[0], 4) + p.line(sample((x) => forwardAt(x, true), X0, X1), COLORS[3], 2, { 'stroke-dasharray': '7 6' }) + cursor(svg, p, s.x, [[forwardAt(s.x, false), COLORS[0]], [backwardAt(s.x, false), COLORS[2]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + stat.replaceChildren(tiles([ + { label: say('SAY_EXACT'), value: fmt(forwardAt(s.x, false), 5), tone: 0 }, + { label: say('SAY_TANH'), value: fmt(forwardAt(s.x, true), 5), tone: 3 }, + { label: say('SAY_DF'), value: fmt(backwardAt(s.x, false), 4), tone: 2 }, + { label: say('SAY_DF_TANH'), value: fmt(backwardAt(s.x, true), 4), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-huber/card.png b/apps/website/public/widgets/nn-huber/card.png new file mode 100644 index 0000000000000000000000000000000000000000..43c8d97748cfbe8e4f80ec4fba7341979cd313f9 GIT binary patch literal 55999 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 + + + + + +Huber loss: a loss that does not panic at an outlier · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Huber loss: a loss that does not panic at an outlier

+

Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/loss/huber_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 15 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-huber/logic.js b/apps/website/public/widgets/nn-huber/logic.js new file mode 100644 index 0000000000..b930f5afc5 --- /dev/null +++ b/apps/website/public/widgets/nn-huber/logic.js @@ -0,0 +1,27 @@ +// Generated by scripts/t27-logic.mjs from huber_loss.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: ff04a9d69fad5628d6aef1141f5d303b8da9a341a4aa9172e9bb36d79ae5c313 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-huber/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABFgNgA319fQF9YAR/f399AX1gAn19AX0DBgUAAQICAgQFAXABAQEFAwEAEQYJAX8BQYCAwAALBz0EBm1lbW9yeQIADXQyN19odWJlcl90d28AAA10MjdfaHViZXJfb25lAAMQdDI3X2VsZW1lbnRfbG9zcwAECqUCBVMBAX8jgICAgABBEGsiAySAgICAACADIAFDAACAP5I4AgwgAyAAQwAAgD+SOAIIIANBCGpBAkGAgMCAACACEIGAgIAAIQEgA0EQaiSAgICAACABC1ECAX0Bf0MAAAAAIQQgASEFAkADQCAFRQ0BIAVBf2ohBSAEIAAqAgAgAioCAJMgAxCCgICAAJIhBCACQQRqIQIgAEEEaiEADAALCyAEIAGzlQsvAQF9AkAgAIsiAiABX0UNACAAIABDAAAAP5SUDwsgASAClCABIAFDAAAAv5SUkgtAAQF/I4CAgIAAQRBrIgIkgICAgAAgAiAAOAIMIAJBDGpBAUGIgMCAACABEIGAgIAAIQAgAkEQaiSAgICAACAACwwAIAAgARCCgICAAAsLFQEAQYCAwAALDAAAgD8AAIA/AAAAAA=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function elementLoss(e, delta) { + return W.t27_element_loss(e, delta); +} +function huberOne(e, delta) { + return W.t27_huber_one(e, delta); +} +function huberTwo(e0, e1, delta) { + return W.t27_huber_two(e0, e1, delta); +} +const __NOT_LOWERED__ = Object.freeze(["forward"]); +export { + __NOT_LOWERED__, + elementLoss, + huberOne, + huberTwo +}; diff --git a/apps/website/public/widgets/nn-huber/logic.t27 b/apps/website/public/widgets/nn-huber/logic.t27 new file mode 100644 index 0000000000..7a872d0878 --- /dev/null +++ b/apps/website/public/widgets/nn-huber/logic.t27 @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Threshold where loss changes from quadratic to linear | φ² + 1/φ² = 3 | TRINITY +// Restored 2026-10-05 from trinity specs/algo/huber_loss.tri: the port kept only +// the first parameter and returned void, so forward computed a value and +// threw it away, and every test asserted `result != undefined`. + +module HuberLoss; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const HuberLossConfig = struct { + delta : f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // per element e = prediction - target: + // |e| <= delta: 0.5 e^2 else: delta |e| - 0.5 delta^2 + fn element_loss(e: f32, delta: f32) -> f32 { + const a = @abs(e); + if (a <= delta) { + return 0.5 * e * e; + } + return delta * a - 0.5 * delta * delta; + } + + // forward(predictions, targets, delta) -> f32. The .tri gives the + // per-element formula only; this returns the MEAN over elements + // (PyTorch HuberLoss default reduction). 0 for n = 0. + fn forward(predictions: []const f32, targets: []const f32, delta: f32) -> f32 { + if (predictions.len == 0) { + return 0.0; + } + var sum_loss : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + sum_loss = sum_loss + element_loss(predictions[i] - targets[i], delta); + i = i + 1; + } + return sum_loss / (predictions.len as f32); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests + // ═══════════════════════════════════════════════════════════ + + fn huber_one(e: f32, delta: f32) -> f32 { + const predictions : [1]f32 = [e]; + const targets : [1]f32 = [0.0]; + return forward(&predictions, &targets, delta); + } + + test quadratic_inside_delta + given result = huber_one(0.5, 1.0) + when negative = huber_one(-0.5, 1.0) + then @abs(result - 0.125) < 0.000001 and result == negative + + // delta |e| - delta^2 / 2 = 3 - 0.5 + test linear_outside_delta + given result = huber_one(3.0, 1.0) + when wide = huber_one(3.0, 2.0) + then @abs(result - 2.5) < 0.000001 and @abs(wide - 4.0) < 0.000001 + + // the two pieces meet with equal value and slope at |e| = delta + test continuous_at_delta + given below = huber_one(0.999, 1.0) + when above = huber_one(1.001, 1.0) + then @abs(above - below - 0.002) < 0.0001 + + // mean of (0.125, 2.5) over two elements + fn huber_two(e0: f32, e1: f32, delta: f32) -> f32 { + const predictions : [2]f32 = [e0 + 1.0, e1 + 1.0]; + const targets : [2]f32 = [1.0, 1.0]; + return forward(&predictions, &targets, delta); + } + + test forward_mean + given result = huber_two(0.5, 3.0, 1.0) + when expected = 1.3125 + then @abs(result - expected) < 0.000001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants + // ═══════════════════════════════════════════════════════════ + + invariant huber_zero_at_target + assert huber_one(0.0, 1.0) == 0.0 diff --git a/apps/website/public/widgets/nn-huber/nn-huber.t27 b/apps/website/public/widgets/nn-huber/nn-huber.t27 new file mode 100644 index 0000000000..2db4401c30 --- /dev/null +++ b/apps/website/public/widgets/nn-huber/nn-huber.t27 @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-huber.t27 -- the Huber loss: square inside delta, linear outside +; Source of truth for public/widgets/nn-huber/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-huber/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/huber_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 15 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the error from -4 to 4 and sets delta from 0.25 to 3. The green +; curve is huber_one(e, delta), the dashed curve huber_one(e, 1000), which never leaves its +; quadratic part on this window, and the tiles huber_two on the spec's pair. + +; WHAT IT DOES NOT CLAIM: the 30-error figure in the hook is the same two fns at e = 30, read off +; the compiled logic, not a measurement of a model. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_huber; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-huber"; +pub const TITLE : str = "Huber loss: a loss that does not panic at an outlier"; +pub const DESCRIPTION : str = "Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square."; +pub const IMAGE_ALT : str = "Huber card at delta 1, error 3: the green Huber curve is a small parabola between the cyan dashed lines at -1 and 1 and then two straight arms; the dashed gold square climbs much faster. Tiles read Huber 2.5000, square 4.5000 and, for the spec's pair of errors (0.5, 3), 1.3125 against 2.3125."; +pub const HOOK : str = "An error of 3 costs 2.5 under Huber with delta 1 and 4.5 squared. At 30 the gap is 29.5 against 450: why robust regression uses it."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/huber_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 15 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_E_LO_C : i16 = -400; +pub const K_E_HI_C : u16 = 400; +pub const K_Y_HI_C : u16 = 800; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [5]u8 = [0, 2, 4, 6, 8]; +pub const K_DELTA_LO_C : u8 = 25; +pub const K_DELTA_HI_C : u16 = 300; +pub const K_WIDE : u16 = 1000; +pub const K_PAIR_C : [2]u16 = [50, 300]; +pub const K_PRESET_E_C : [4]i16 = [300, 50, -300, 200]; +pub const K_PRESET_DELTA_C : [4]u16 = [100, 100, 50, 300]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Error 3, delta 1", "Error 0.5, delta 1", "Error -3, delta 0.5", "Error 2, delta 3"]; +pub const SAY_ASK : str = "Can a loss stay calm when one data point is far off?"; +pub const SAY_E : str = "error e"; +pub const SAY_DELTA : str = "delta"; +pub const SAY_HUBER : str = "Huber"; +pub const SAY_SQUARE : str = "half the square"; +pub const SAY_PLOT_LABEL : str = "Huber loss and half the squared error as the error goes from -4 to 4"; +pub const SAY_PAIR : str = "Huber of ({0}, {1})"; +pub const SAY_PAIR_SQ : str = "square of ({0}, {1})"; +pub const SAY_NOTE : str = "Inside delta Huber is the square; outside it is delta |e| - delta^2 / 2, joined so that value and slope agree. Its gradient never grows past delta."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/huber_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_wide_delta_never_clips_the_window { + assert K_WIDE * 100 > K_E_HI_C; + assert K_DELTA_HI_C < K_WIDE * 100; +} + +test the_pair_is_the_spec_example { + assert K_PAIR_C[0] == 50; + assert K_PAIR_C[1] == 300; + assert K_PRESET_DELTA_C[3] == K_DELTA_HI_C; +} diff --git a/apps/website/public/widgets/nn-huber/tool.js b/apps/website/public/widgets/nn-huber/tool.js new file mode 100644 index 0000000000..54845a044c --- /dev/null +++ b/apps/website/public/widgets/nn-huber/tool.js @@ -0,0 +1,40 @@ +// nn-huber/tool.js -- lesson 15 of neural-networks: a loss that does not panic at an outlier. Huber +// is half the squared error inside delta and only linear outside it, so one wild miss pulls on the +// model with a bounded force. Both curves and every tile are huber_one and huber_two of gHashTag/t27 +// specs/ml/loss/huber_loss.t27, compiled to wasm (./logic.js); the dashed curve is the same fn with +// a delta so wide (K_WIDE) that it never leaves its quadratic part. Words are SAY_ and numbers K_ +// constants of specs/widgets/nn-huber.t27. +import { huberOne, huberTwo } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, svgEl, tiles } from '../nn-kit.js' + +const E0 = centi(K('K_E_LO_C', -400)), E1 = centi(K('K_E_HI_C', 400)) +const WIDE = K('K_WIDE', 1000) +const ctl = controls([ + { key: 'e', label: say('SAY_E'), min: E0, max: E1, step: 0.05, fmt: (v) => fmt(v, 2) }, + { key: 'delta', label: say('SAY_DELTA'), min: centi(K('K_DELTA_LO_C', 25)), max: centi(K('K_DELTA_HI_C', 300)), step: 0.05, fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { e: K('K_PRESET_E_C', []).map(centi), delta: K('K_PRESET_DELTA_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_HUBER'), COLORS[0]], [say('SAY_SQUARE'), COLORS[1], true], [say('SAY_DELTA'), COLORS[2], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: E0, x1: E1, y0: 0, y1: centi(K('K_Y_HI_C', 800)), xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_E') } + const p = plot(svg, o) + for (const d of [s.delta, -s.delta]) svg.append(svgEl('line', { x1: p.x(d), x2: p.x(d), y1: p.top, y2: p.clampY(-Infinity), stroke: COLORS[2], 'stroke-dasharray': '3 5', 'stroke-width': 2 })) + p.line(sample((e) => huberOne(e, WIDE), E0, E1), COLORS[1], 2, { 'stroke-dasharray': '7 6' }) + p.line(sample((e) => huberOne(e, s.delta), E0, E1), COLORS[0], 4) + cursor(svg, p, s.e, [[huberOne(s.e, s.delta), COLORS[0]], [huberOne(s.e, WIDE), COLORS[1]]]) + dragX(svg, p, o, (e) => ctl.set('e', e)) + const pair = K('K_PAIR_C', []).map(centi) + stat.replaceChildren(tiles([ + { label: say('SAY_HUBER'), value: fmt(huberOne(s.e, s.delta), 4), tone: 0 }, + { label: say('SAY_SQUARE'), value: fmt(huberOne(s.e, WIDE), 4), tone: 1 }, + { label: fill2(say('SAY_PAIR'), pair), value: fmt(huberTwo(pair[0], pair[1], s.delta), 4), tone: 2 }, + { label: fill2(say('SAY_PAIR_SQ'), pair), value: fmt(huberTwo(pair[0], pair[1], WIDE), 4), tone: 6 }, + ])) +} +const fill2 = (w, v) => String(w).replace('{0}', fmt(v[0], 1)).replace('{1}', fmt(v[1], 1)) + +ctl.start() diff --git a/apps/website/public/widgets/nn-kit.css b/apps/website/public/widgets/nn-kit.css new file mode 100644 index 0000000000..b5b355a71b --- /dev/null +++ b/apps/website/public/widgets/nn-kit.css @@ -0,0 +1,22 @@ +/* nn-kit.css -- the drawing the neural-networks widgets add to dsp-kit.css: the opening question, + a drag surface, bars, heat-map cells and node labels. Every tap target is at least 44px tall on + a phone; a heat-map cell you can tap is drawn at least 44px wide in the 390px layout. */ +.nn-ask { margin: 0 0 10px; padding: 10px 12px; border-left: 4px solid var(--c1); border-radius: 8px; background: color-mix(in srgb, var(--c1) 8%, var(--w-panel)); color: #fff; font: 700 0.95rem/1.4 var(--w-mono); } +.nn-drag { touch-action: none; cursor: ew-resize; } +.nn-cursor { stroke: #fff; stroke-width: 1.5; stroke-dasharray: 4 4; opacity: 0.7; } +.nn-bar { filter: drop-shadow(0 0 6px rgba(0, 255, 136, 0.18)); } +.nn-bar-value { font: 700 14px var(--w-mono); } +.nn-cell { cursor: default; } +.nn-cell[role="button"] { cursor: pointer; } +.nn-cell[role="button"]:focus-visible rect { stroke: var(--c1); stroke-width: 3; } +.nn-cell-text { font-family: var(--w-mono); font-weight: 700; pointer-events: none; } +.nn-on rect { stroke: #fff; stroke-width: 3; } +.nn-dim { opacity: 0.32; } +.nn-node-text { font: 700 13px var(--w-mono); pointer-events: none; } +.nn-edge-label { fill: var(--w-text); font: 11px var(--w-mono); paint-order: stroke; stroke: #020403; stroke-width: 3px; } +.nn-steps { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; } +.nn-steps .t27-btn { min-width: 44px; min-height: 44px; font: 700 0.9rem var(--w-mono); } +.nn-two { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; } +@container (min-width: 700px) { .nn-two { grid-template-columns: repeat(2, minmax(0, 1fr)); } } +.nn-cap { margin: 4px 0 0; color: var(--w-muted); font: 0.74rem var(--w-mono); text-align: center; } +.dk-range { height: 44px; } diff --git a/apps/website/public/widgets/nn-kit.js b/apps/website/public/widgets/nn-kit.js new file mode 100644 index 0000000000..5478a330e7 --- /dev/null +++ b/apps/website/public/widgets/nn-kit.js @@ -0,0 +1,193 @@ +// nn-kit.js -- the drawing the neural-networks widgets share, on top of dsp-kit.js (sliders, presets, +// the URL hash, stat tiles, plot axes): function curves you drag along, bar charts, heat-maps, the +// diverging and heat colour scales, and node-link diagrams. It computes nothing about networks: +// every value a widget shows comes from that widget's ./logic.js, the fn bodies of a gHashTag/t27 +// specs/ml spec compiled to wasm. Every word is a SAY_ and every range a K_ constant of the +// widget's own spec (window.T27_WIDGET). Inputs stay in this tab and in the URL hash. +import { COLORS, el, svgEl } from './dsp-kit.js' + +export * from './dsp-kit.js' + +const css = document.createElement('link') +css.rel = 'stylesheet' +css.href = new URL('./nn-kit.css', import.meta.url).href +document.head.appendChild(css) + +/** A spec number written in hundredths (the widget specs hold integers only), as a number. */ +export const centi = (v) => Number(v) / 100 + +/** A value for the page, with a fixed number of decimals and an honest minus sign. */ +export const fmt = (v, digits = 3) => (Number.isFinite(v) ? v.toFixed(digits).replace(/^-(0\.0*)$/, '$1').replace('-', '−') : String(v)) + +const mix = (a, b, t) => a.map((x, i) => Math.round(x + (b[i] - x) * t)) +const rgb = (c) => `rgb(${c[0]},${c[1]},${c[2]})` +const NEG = [255, 77, 109] +const MID = [10, 18, 16] +const POS = [0, 255, 136] + +/** Diverging colour: pink below zero, near black at zero, green above; m is the value at full colour. */ +export function tone(v, m = 1) { + const t = Math.max(-1, Math.min(1, m ? v / m : 0)) + return rgb(t < 0 ? mix(MID, NEG, -t) : mix(MID, POS, t)) +} + +const HEAT = [[8, 12, 30], [56, 189, 248], [0, 255, 136], [255, 215, 0], [255, 255, 255]] +/** Sequential colour for t in 0..1: deep blue, cyan, green, gold, white. */ +export function heatTone(t) { + const x = Math.max(0, Math.min(1, Number.isFinite(t) ? t : 0)) * (HEAT.length - 1) + const i = Math.min(HEAT.length - 2, Math.floor(x)) + return rgb(mix(HEAT[i], HEAT[i + 1], x - i)) +} + +/** Black or white text, whichever reads on the fill. */ +const inkOn = (fill) => { + const [r, g, b] = fill.match(/\d+/g).map(Number) + return 0.2126 * r + 0.7152 * g + 0.0722 * b > 140 ? '#020403' : '#ffffff' +} + +/** + * Drag along a plot: a pointer anywhere on the SVG moves the cursor to that x (in data units, + * clamped to the plot). The whole drawing is the target, so a finger never has to find a dot. + */ +export function dragX(svg, p, o, onX) { + svg.nnPlot = { x0: o.x0, x1: o.x1, left: p.left, right: p.right } + if (svg.dataset.nnDrag) return + svg.dataset.nnDrag = '1' + svg.classList.add('nn-drag') + const toX = (ev) => { + const box = svg.getBoundingClientRect() + const vb = svg.viewBox.baseVal + const sx = ((ev.clientX - box.left) / box.width) * vb.width + const cur = svg.nnPlot + const v = cur.x0 + ((sx - cur.left) / (vb.width - cur.left - cur.right)) * (cur.x1 - cur.x0) + return Math.max(cur.x0, Math.min(cur.x1, v)) + } + let down = false + svg.addEventListener('pointerdown', (ev) => { down = true; svg.setPointerCapture?.(ev.pointerId); onX(toX(ev)) }) + svg.addEventListener('pointermove', (ev) => { if (down) onX(toX(ev)) }) + const up = () => { down = false } + svg.addEventListener('pointerup', up) + svg.addEventListener('pointercancel', up) +} + +/** A vertical cursor at x with a dot on each curve value given as [y, colour]. */ +export function cursor(svg, p, x, dots) { + svg.append(svgEl('line', { x1: p.x(x), x2: p.x(x), y1: p.top, y2: p.clampY(-Infinity), class: 'nn-cursor' })) + for (const [y, c] of dots) { + if (!Number.isFinite(y)) continue + svg.append(svgEl('circle', { cx: p.x(x), cy: p.clampY(y), r: 9, fill: c, opacity: 0.25 })) + svg.append(svgEl('circle', { cx: p.x(x), cy: p.clampY(y), r: 5, fill: c, stroke: '#020403', 'stroke-width': 2 })) + } +} + +/** Samples a spec function on [x0, x1] for a curve: [[x, f(x)], ...]. */ +export function sample(f, x0, x1, n = 160) { + const out = [] + for (let i = 0; i <= n; i++) { + const x = x0 + ((x1 - x0) * i) / n + out.push([x, f(x)]) + } + return out +} + +/** A legend row: [[word, colour, dashed?], ...]. */ +export const legend = (items) => el('p', { class: 'dk-legend' }, items.map(([w, c, dashed]) => el('span', {}, el('i', { style: `background:${c};${dashed ? 'opacity:0.6' : ''}` }), w))) + +/** + * A bar chart into an SVG. o: { values, labels, colors, lo, hi, fmt, w, h, title }. Bars grow from + * zero, each value printed on its bar. + */ +export function bars(svg, o) { + const w = o.w ?? 640, h = o.h ?? 260, left = 44, right = 12, top = 26, bottom = 34 + svg.replaceChildren() + svg.setAttribute('viewBox', `0 0 ${w} ${h}`) + const lo = o.lo ?? 0, hi = o.hi ?? 1 + const py = (v) => h - bottom - ((v - lo) / (hi - lo || 1)) * (h - top - bottom) + svg.append(svgEl('rect', { x: left, y: top, width: w - left - right, height: h - top - bottom, class: 'dk-plotbg' })) + for (const t of o.ticks ?? []) { + svg.append(svgEl('line', { x1: left, x2: w - right, y1: py(t), y2: py(t), class: 'dk-grid' })) + svg.append(svgEl('text', { x: left - 6, y: py(t) + 4, class: 'dk-tick', 'text-anchor': 'end' }, o.tickFmt ? o.tickFmt(t) : t)) + } + const n = o.values.length + const slot = (w - left - right) / n + const bw = Math.min(110, slot * 0.64) + o.values.forEach((v, i) => { + const c = o.colors?.[i] ?? COLORS[i % COLORS.length] + const x = left + slot * i + (slot - bw) / 2 + const y0 = py(Math.max(lo, Math.min(hi, 0))), y1 = py(Math.max(lo, Math.min(hi, v))) + svg.append(svgEl('rect', { x, y: Math.min(y0, y1), width: bw, height: Math.max(1, Math.abs(y1 - y0)), rx: 6, fill: c, class: 'nn-bar' })) + svg.append(svgEl('text', { x: x + bw / 2, y: Math.min(y0, y1) - 7, class: 'nn-bar-value', 'text-anchor': 'middle', fill: c }, o.fmt ? o.fmt(v) : fmt(v))) + svg.append(svgEl('text', { x: x + bw / 2, y: h - 12, class: 'dk-tick', 'text-anchor': 'middle' }, o.labels?.[i] ?? i)) + }) +} + +/** + * A heat-map into an SVG. o: { rows, cols, value(r, c), color(v) (default heatTone over lo..hi), + * lo, hi, fmt, rowLabels, colLabels, w, cell, cellH (row height, default cell), mark(r, c) -> 'on' | + * 'dim' | '', onTap(r, c) }. + * Each cell prints its value; a tapped cell calls onTap. Returns the cell size. + */ +export function heat(svg, o) { + const left = o.rowLabels ? (o.labelWidth ?? 74) : 6, top = o.colLabels ? 26 : 6 + const w = o.w ?? 640 + const cell = o.cell ?? Math.min(96, (w - left - 6) / o.cols) + const ch = o.cellH ?? cell + const h = top + ch * o.rows + 6 + svg.replaceChildren() + svg.setAttribute('viewBox', `0 0 ${w} ${h}`) + // A small drawing scales up to the phone's width but not past a readable size on a desktop. + svg.style.maxWidth = `${Math.round(w * 1.3)}px` + const color = o.color ?? ((v) => heatTone(((v - (o.lo ?? 0)) / ((o.hi ?? 1) - (o.lo ?? 0) || 1)))) + const x0 = left + (w - left - 6 - cell * o.cols) / 2 + for (let c = 0; c < o.cols; c++) if (o.colLabels) svg.append(svgEl('text', { x: x0 + cell * (c + 0.5), y: 18, class: 'dk-tick', 'text-anchor': 'middle' }, o.colLabels[c])) + for (let r = 0; r < o.rows; r++) { + if (o.rowLabels) svg.append(svgEl('text', { x: x0 - 8, y: top + ch * (r + 0.5) + 4, class: 'dk-tick', 'text-anchor': 'end' }, o.rowLabels[r])) + for (let c = 0; c < o.cols; c++) { + const v = o.value(r, c) + const fill = color(v) + const m = o.mark?.(r, c) ?? '' + const g = svgEl('g', { class: `nn-cell ${m ? `nn-${m}` : ''}` }) + const gap = ch < 20 ? 0.5 : 1.5 + g.append(svgEl('rect', { x: x0 + cell * c + 1.5, y: top + ch * r + gap, width: cell - 3, height: ch - 2 * gap, rx: Math.min(10, ch / 6), fill })) + if (o.fmt !== null && ch >= 26) g.append(svgEl('text', { x: x0 + cell * (c + 0.5), y: top + ch * (r + 0.5) + 4, 'text-anchor': 'middle', class: 'nn-cell-text', fill: inkOn(fill), style: `font-size:${Math.max(9, Math.min(15, cell / 4.2))}px` }, (o.fmt ?? fmt)(v))) + if (o.onTap) { + g.setAttribute('role', 'button') + g.setAttribute('tabindex', '0') + g.addEventListener('click', () => o.onTap(r, c)) + g.addEventListener('keydown', (ev) => { if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); o.onTap(r, c) } }) + } + svg.append(g) + } + } + return { cell, cellH: ch, x0, top, h } +} + +/** + * A node-link diagram. layers: [[{ label, value, color }], ...] left to right; edges: + * [{ from: [layer, i], to: [layer, j], value, label }] coloured by tone(value, m). o: { w, h, m }. + */ +export function net(svg, layers, edges, o = {}) { + const w = o.w ?? 640, h = o.h ?? 300 + svg.replaceChildren() + svg.setAttribute('viewBox', `0 0 ${w} ${h}`) + svg.style.maxWidth = `${Math.round(w * 1.3)}px` + const pos = layers.map((nodes, l) => nodes.map((_, i) => [70 + ((w - 140) * l) / Math.max(1, layers.length - 1), h / 2 + (i - (nodes.length - 1) / 2) * Math.min(86, (h - 60) / Math.max(1, nodes.length - 1 || 1))])) + for (const e of edges) { + const [a, b] = [pos[e.from[0]][e.from[1]], pos[e.to[0]][e.to[1]]] + const m = o.m ?? 1 + svg.append(svgEl('line', { x1: a[0], y1: a[1], x2: b[0], y2: b[1], stroke: tone(e.value, m), 'stroke-width': 2 + 6 * Math.min(1, Math.abs(e.value) / m), 'stroke-linecap': 'round', opacity: 0.9 })) + if (e.label != null) { + const t = 0.62 + svg.append(svgEl('text', { x: a[0] + (b[0] - a[0]) * t, y: a[1] + (b[1] - a[1]) * t - 6, class: 'nn-edge-label', 'text-anchor': 'middle' }, e.label)) + } + } + layers.forEach((nodes, l) => nodes.forEach((n, i) => { + const [x, y] = pos[l][i] + svg.append(svgEl('circle', { cx: x, cy: y, r: 24, fill: n.color ?? '#0b1512', stroke: n.ring ?? COLORS[l % COLORS.length], 'stroke-width': 3 })) + svg.append(svgEl('text', { x, y: y + 5, 'text-anchor': 'middle', class: 'nn-node-text', fill: n.color ? inkOn(n.color) : '#fff' }, n.value ?? '')) + if (n.label) svg.append(svgEl('text', { x, y: y - 32, 'text-anchor': 'middle', class: 'dk-txt-dim' }, n.label)) + })) +} + +/** A heading question over the widget: the question the lesson opens with. */ +export const ask = (text) => el('p', { class: 'nn-ask' }, text) diff --git a/apps/website/public/widgets/nn-lamb/card.png b/apps/website/public/widgets/nn-lamb/card.png new file mode 100644 index 0000000000000000000000000000000000000000..148009ff1d05f444f2a59b8c8c5b51a27ba6368b GIT binary patch literal 45118 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ⓝ(FD66`ICw*n7^z`?>@}iP43Pkl$i};76 zeQ2O2dl;*t53|g7eHjWVx<;YZ_^UqTAZN6D!hnLTXpbaj{diTPgOFvnJ{dO_)5)o1 zjvkH zYY4CyVip}mSkidoQ}{rO>y{z6g)s^(xeP&5{6`-b{Ov%@?DgU z#^9T(cuPb{qgCmm)K8F?^%^T6h|P`6hLL9^6`sCdpn#!OkQPF(Lo3aAxo@(hZbsmS z;i==R-Tq$3L3=2^-IJYP1r28Uf8700YZd}bx!v+PN40L3oJr6;SAG%8)jrtQD_U1! zc-#v^o=Dae{KYG$Ho#rjK`o|u24`mK8U8gI5!L%Xw7YcZRBn)Zj#t%&f^sZa721csdfE_J!UD)usV~w9C^!@B(jsPcR-eG;qv)@^eR$E$e z%f-&l47~5W$09liD4yZ)NYjKj?djjo)R*y&V)-f8_yw(D8dT2}ZvZoY`-b97KzPj5 z*%^>EjCnv*!9>E2NYjJdK*=(leC{WQcMSW6V;R2?k)R;*W|Thj$CmA?kVE&vw^4<@ zTukx3e6o>FQJQU>5UI>|((0iD&yeo~CPEgY#DMAwmAvBRcJjzTjhkFeOnLosU^7q&83e2IwOBXye&XQf74hQFB&s35}-%_ zD)dZNOMu^aV{OAQi;~ZP(zin%U= zf!O}5Gr7=RX1lW^d#Xg)JW;gpFfnRk=GxR!%J8sDp^Z`?cZv@w^Cpy#@|a`F z>ibY0SNMmG0(GNEslG7H+6>bDl~D7p1%i)PXL}=+opwkm2NtwAJ}+ z&Fwq0w97&w;Gg{n+gy+Ah_6QK32&Q3O1T+Hn7;4QVa+(~j})6X<$v$1)!)5#PBq~> z-KGsX_kJ0RGQe83Hw`UFQnT${i(vkoi3UtL74nk;*Gz@;5T0y>FkKVmF)rSXjcL1_ zP_s+BH#yX!LWI}`%!!&K`tdi(1PL*~@#YxrUFViz)vlo~BLIQAi$F+;sPXPd9|z;D zzO!R>tYB#B-5LKAqfzz!nxXE7V|*~KP({#RW_0QKeQplo-MI1ub-n<`HAYG{l$Pp_ z#KFy%tu`IoqQ`>q4A$P&LfN3N$*^jZ5@dwfeMW0K>hK)i{>=-T0a<)1m z)6>l;(9`@nlGRM8(x~{sF10>jjXK^#(-pv!GrG`n8g1rbqxnV8eF;U*@U%XqWzW@K zT$sTJdr4~6!=rZ!w`h|SzSe5l&hU{Itwcu{&qxgzX1ZPjuB z`mzeqg2u$Bs;u^{6>#YoqF#h`=iU|jN+`_;zjJqksZVsuWhZMjD4vcqt$Wh5U@53C z1yO9~6K@=)jV$&rKxui&DDFx#Z+%}?G9Jv2S@ei>4dUr1Yjaqdh;D=egV`@VSPnPU z+=>Und72K|@SWf^bL|u|r}s^V;j`JV9%?L)mn(w52lPwUdHkrL_RWktG*|yT;?**< zpQn`tAN2gBV;F^Ogh1w0j_MM2S3gFhHHMs=BBReE+t;TIX znyjC44QgCR8sGF|t^12BtE;B%g#_k^pMTFiOmX!JRp5vHYtPH8f9lNQdA1q<{-U8y zI63B^cx6T6po3)QzKiV7l7re{jynTm(FR%JHktFrc zhFjIa>k~~%*!&8ZQ2W_@(U%WmwakTTlFIFy!pXxY9F;7@1<8w-N@Ih~-k}PaesjOs zP}Aauuidzf!LLCj1CaIrR4WYp|G5nk1^e{f@F z<+8TFj%!J16keTdxni$Yy;px-T}|Q4Qzzw4Uyt2q_Fu`T;e26B}iYM>?N*{dczL@$R@LvJ7+ei~B%3^hFWrgZ-zM z5k-qXL5!_jS(0Dk;Y<8ok-^$Ba(-*GkB)9y4@n&7fp4Y#{ab>S<0%Y|A z&EDa1bzJyaFWpjj2^KoCspxos( zQ0q;Rh}Za$g7K*>$^7yaZe2^z-KupaE$K|7URgoxm$#9$PSd>v+IIdWz5ciF*e<+X z{3xEIcv=tLSz9491X=rEaz5kn=kCsGGUCQ9UjFR^M(f{v+E21GcJv=5sAnc(FoK?u z81v9>&4(FBeA^T++$X~PSk3;P;SNh;D(wat>&*AIygK#AY5F6l{jSuYtku_!K`+K9 z^w|r8zDvHQAvJH<6S0Ta`Wx0^SJa#KPfsb&V|lmVc*A$&56!<+@Nc&M|GX~wpHDgd z8(}$=ZT#N(>}x_l!%@Z{lVbY-wU^Ntkzvc z+4e!4F9w2CF*|s5-x;4_TX~TGV85WDr&y>6{dpl-5%i+1>x0l)n1x@nk9{X4g z&K&s;uBQT%Kue{W6<8SmU76HPk;m%9I-F8CJ7Btgtr_*R%dIQet$sTTYN+NFjN|6Y zqj821huEUl+`irW%EQc?iHJ8JmT#pzV8-Zr3Z6|P8hl{N{`LgnW3}AS^jQWeGf+j} z$c&171uY}W8>r=T9b`G zx*lnxjs&(HH7(hBZ@nazcU+kK0y}HfEh$_3BfN^ASOSTxY0+Cnc2-sdtpQ(bn(+Eaax8pwT~N z`D%~5P<|nnXzCVsfH5Y`4bkLnx+^Ijlh*>_*JgE$_2G`J(3OEmKDwxPZru>A| zbvxUc-0VET6xQKxDzNYKSqTsuv-j=?mx+kTy@)sB5~u{+4K^l6r@b~30!)3_PX$)H zl<0T=F0d-6Ai+m7A8UBZ(RhEQha|W*3pY3!PtlvshPj63dSj0}@CX%{wF;kJnc~5c zEPW#^xss}qTMv(BWadLWG^Dfw8T@3y=+_5kuhUeeemtET`{qiL-=rEDpArdRaRnvvBL~1i9c4wXBx*-WdvWd<^Y-3I^gT!2 z<3aTz7juZm!%Z|;&Qo)ix3P%iudmg%+i;UL)-*~+(!&{hIcdt0g4puejuMSyckda` zv0)Pyd(@tG783-qfY}yltqyw|0vDOAdQXh%T(SM%Rl8I~2S993pZFk|6TnEw@Kj4~ zOj`P7OyXHSeE&E?&Oq2aDKiQ1meZ9{yXA-XJJ`(iU>8JD=wj%h;oR9Vue?%(OV+}` z&pd&XM1MM4Ckrg2wm4@tNBkm&k17FvY1ck!BNgiq5}7@CYz@EjMPU&p$4X^>DB;I{X)T zFqvzpIxFD#YIG#~Db|kmkj7z=Dam4?T9Bak{0xRkHTF!gMuvT~D7dICAKv3e7bvRm zGQy>Eznc>jV=m9dAB1$%<8++7CuK|x50M4cng+!j!Dx9P4VUfia+RgPJ(R1cDwOv# z4eD`+)6DieOXi}X&Ac#Zf6-^$FJP9U+_^ISZmJ86R3C06S^UYe;a?NuiqeZESw%Z7 zj?4U63>Un5NnB-B=(1DaB~f|=CkpcCf|UESv^&XH{M06r%mZ89~bpk=0>TdmV&qp4aPf2$)_rNJBN)f{UAvgaCWif9YLaOx@Z7O zQ%1s+UMJJ*Ky0-@swp7I6dCqYV?*hngqUX@tnc~1>%EfN1KwyH)MLK% zb1|AM4R+iByj{4mgQZ3%Qo85L5U$NG%zVnW4@&QDZ*~U@ZC~l>u1KK$jarfnoE=-` z_u>DB7g;4gfPgt>1>c5y7O6Ac{6%z571*>HZHfL!>gv~%E6COqDtx}dobliT))!wo zi#-|W+&Ql8FPj({L7#WKHGP`Uls*6JB`$I}MoNCcMY2`%l}1i{iZxzM@u@oIU>1(Y zj+*TZat91iB0g|aifDhCRWydk{rYG9bBYO%5M!aBc}e%pUv1YRpRnu*Vo6#`IZ8Q+ zOtkxRJ7`T7)|Q)Z>h0F^9!Mg!L{u-$x9F@E!}{4x}~di|1p;5)JtLMyulB z2ag3Q6(s;twTCamwZfP^9x&OFH~)uQkD4$fXnPZx1rCbJk29yp3s$+R4B3e*`XlP; zsL*)mJ60vB2eTc%Xl_M{ZTsWDO^9z9uMpM0q}lTVtk5SMkUZ%KbZPG57w(gx5Fsrf z6;~L~LoymE>XQ&|oGp^4dFt^yBl-Wd{+q8V|C^=wfA_r6|G2LI-w?Ks=JQ_5)JWoB z@^(K!u^~xP9`{dLV*JVi)u&asY80|@PV7fbtFNYh$4<}5*X#es_M-|t(KppKnFLw+ z-dgJyehXQ0Eo1vAzfneTE-(QRW3py?8YyVZ6~@&kNfNZ=>BjvA4MAIb;yM3rt+oYk zok|f3u&6kmoHNxml;bWbeYWE|mHGfTda6W;bVBZ}k*rrw0Q|I*QzAA$ z`x?KCpB*nwuPt2)q5kV9JT@w7Wot|HN#c>FA}{1%T|W48dU4&mKcF==6~6YVrPH^t zg6dapnT`k;zl|0^IC7hro^J2z!g%V&jico7eH~wxJsP{SKBi3O#miX-d0ZL>%X2NC zC6YlJ#G~X7czB#&zNo6Ie&lkb1H1xt{qBdZ?lcof=KdTgxgr5!$)#st zVEy{#!~KnwrsEU%OZ6kYZ^l5W0v6_l>XhV>+Bb=q=)dPggr)Ty3qULh&qi}~Fs6_x z4wdY1eu}8~lXQfm(Xn0(lic-@Ub}2Swk2A7%r2RM+Vuf_q&}YoW{er-7i3{6C#t{J#;u|2_!$|5R8Zo7Zqh zlnE(`23ZBGVMzOPgb5wH^~dc_l-+dp#~|^%23t#EsbX9W+Rn)+6x0vTzU{1SRQ8y} zBo9*NRE#*~58Cf*1kvpa8rG27%?V%oJqmD9jVS6CmD4AuB_!{8ua{qHPM&ym`zgNEdIPrIKoptIZ0sBIig`eHPi=`o)D!*hd*j(hVmJ$X8&XHoM!0jHK+<6V?^0Gy86dxCQGXe4C|6<(_p@)at5F}P+!C@sZd4nZ+kEB?tKzf@&jmq=BLif- zt)PsOF5g&?WZ6-s+@j0POC6aRCZ3iTnt% z03o%4-dAG67NAw0n;6`l35EyZ+U+sn+w3f|mC+?9u1@{UjI+PSBUup4BM zrA;$R{8PatVjvj>yJ;llbF^Y*cAbq~7cQ;1Wgek+nPizsJP(3mAr*iOuookiH{}o_ zS)@HW+ti`qtsFPc^R9`9d6V$3p9Dp1d0-9^6$TnwWT(2#W9?kQIXM-BIKj@Pw0DziaMI!P;<}9UZCaFvhQ1wM`wZG zrh90H>I&+14yx}z^DEK*Y`d#$d-LnKr1+VUEMh*9Z*3Xt`ye4~#~p0z3eS#u6O&yo z@D;nkJ9VP3cL6d`O3a`Ea#M}8$Fn07%g0ibU%U{~Q$Nvtt{v^swjkb{E!{i!wa(`I z=Gs=#Kky|tFm%??V0w1-c)tlB2N_`pRU^S!Lcf6LEvKW48y6=}0z&%2kBc#@LheJ z8*6&@*sjXG>qPoul#*3rP;Xp!%L%-dRSp(cN-(!)({u4gB~`4}wJMvGb|Vc2@c_O9 z$@X9%LD1AI+_?9zjJLfSugeB+rfF@@dNH>3XIxGi^*B`nF->r4itmBk5T8N4xU!F} zyh0wXr#S*GmiM&6CNoaUK|N9o#crN{S`^8(VUzc2njF?loA25IpID&R` z7d8d5g@+_8+ZkBhVXtO#P`8OTHT2Ij8tLvzaB7W|_Yt-oqtBc~HuKW^Dn zEh^t@aK+upXQ$I7*h8vs&!(-EQ|lCtVOA3s2ZbDAQ!1YK7Wpwg*kwakM`sBRpcmw8 z(a@VMbR)Ho4}0;!{6jL(wAqGJ1^IV3b4DNnY&1~yxIa-+behMm?ay3`ysX#b+*Z4M zmATjU7Lpkd-m9H)L<6iMD*J@Xj!o~_MjSd?HL;A~q0ORBZdc!{_!hMvzPTQ79V71w zn!?!ntoKROIuW#<6&oqJES&ET=}M-e{KOpM_`0^I`Q42cEU5Q_;3X{ zQ|4)A=AJ>yvoy!**{O!6UhQTNx0TS>QoT7Sd!ZNaIl6da)5CsP+8B3uX)GpmeU=X6 zwQNjKoKXJe=S?ra^`Ve}K+i;d@;Zo6dFEQOQA*>=bv`IIZza{-{jfMi&(r|kt#k!HS^hPWI?zjrmt6w7bCv*}|L?xJAk7!19jGy?t<>M0Cz}Um#H)trZmE$$Cdim6b;b^MPWnR~q>+Gy%VY6IiLqZz ztoY(h)#?$snLkV5ebS{nz>Gky$XBXak*&D9eA-QRwA0?C9auqb!?| znc!k;%~qHg`T}3ea(H<3Lt+jei^cgqw^vzeQ%P&mF>a(K0XWzB2?X^WrZ(# z!_p>n(KlCx-(*-mfXNUCBb=JdIjb4`_9`t7`#rh!&tL4qN#KZh`wu434-Ffgnf<;q z+e0l}5o&fpTB{vDFE>34tTrD*0yu{3l&DEBTB7=W3=uXn3wVq)FI1h^dJ1$;9RTi!p>3&`Hi zYZ2TUWI$Y>s|t_MzkiQvHoV+QB{YZfx-(DsiK81fhpx`?j6XX3nKPb6I6jbZKTDzM zj^MuVUGC628Th!*)7WtKmrSp9Zaxfo(%EixI!sJy1d)sefrCbhd$UD)A^TKq7uxbx z$FFN1p_(?X1~_i4Wg)p@o3P~mTao*#J~G5R+l2%bFX6gWI~z*pMw%Pp43dV_ra~t+ zWB$?@q83%$h-+Z1XPcy`la*ADtPriTc>ihfMpUTwr==;AS%mRHxVLkKQ($PBKh@EV zoB3x0sHlYhfvZFxSFUxS4<$p{^^RvLDhywe8}hk<15jxQkyOS~sJeSLm+k6qs%{)0 zcDGvne71M*0H&I?zoXFi*(oM@s^ibzT~D6}C4Axt`A?a^oSaCFvBw6Q!pY++IVAKj z(S2bjNX(IGB)10DJF_MD@F5<6>J~2S>&viJwJP%|5S?Id}yJs{jdXV#{JaV#-4LjeW+p&VpWjg4=FXUnJ`w|LQhgNnRI07o`ZH@ZdzLp z7iU$V^mq&^{zUF0k6OpOR=f}7W7BzN1p$~pJWZQs(TQAU9UlA*VBsFWv36liaA!iY zS+dume5L`^+WJoZt&68EcE%6=4h(}fn^mJSzf2eMFu1WGZKZx z1`bIx?q$wIMjiU)M(=H>7IZJxw&_>_yWgp@zU!tjDp{dJ7ozL#-iu4Ucjs4=M3zu2 zF*if>sLO$~*%E^5Sxga%A*- z=xHZ%wIy2w2`K+h@b~C#&X!77^ZB0t9K60v1>7ae-R}#?>G<5e-_&o%3&zC1Uom$qE zuftRCZGA0IRMfID$DKQ*^m)f^D?l{7Xn5YI2T6qe$R=9b${!t3(RyOEXq5H(e%R%l z?#mohl}JG8W7-b&8;@h{pbQkCr3*7u(x_w)U8G@~cD4~arHqu0o|h0kF&sKX0njz5 z$n)bIQV!#vyISyNUI0O^WZ=4UGa^3e05FkDF9i6qKEyq4J-02ZFfk*gkg@2vUuwY2 z62F}UjJyS(zpn=h`8uBOy1Y%%alWsbP!``&!V?t_nEJUXEh~|UChd2=IomEW6-?0S zpvm$cUvsf0;6`2z{v0HG;p*{d07HkmFfmQsuI6m0U3oz6b>;}QeRv@So9SU*fk5VR zKq=myEB@@Y;=A!to1@7y*g5xRmFXIdfR~H3 z>vFApq!_ZLZlmNL#=VrreU$@S!XtG!TQW8~kP|6o=Ny5ODH)X)fXN^d$d6RbWS znkBB8L?q9Dc{v-zQ0xMUM9S>@c$8XBVCiSX(N9%kDozbYv^I@ET0LQTMF0~*9Z9^D z2hY9+wg)`{DEpqnOBn7JC;M|{=>|YYG(eA}LT6;37a#nFNao(8Ej!#qkYu(s4i<2y z(Z^{f5wSnzW2@hPbH0Pmue|+`{##8UNvT4%x(lRtR{NdK8sAQtXzOSOL!Hy!QHRop zz{tYU_{dR)jUR7(g+ZdXIt3_1?CzU4%&8{NJC|k%xl>V=lu)s?>E1wI6zvm{7)}^V zR<)=q{rW=LL6HnV9&-(CfSx zMJZLEewR=Fs=$1ZNVhUUZ*6{Ta;GMFwk%W>rnN_Q=3E+Yd-%z3U%Eu0YnY$_gFGlT zf!4_0Lk67Kl~tPsm3htBSjoz_IW_ro+3Y>*(R#vtzt4NP$(gGYaF8p&D`4UxzF^brZi46?mbWt|Tr52}g1q#?M16$Gy1ly0 zdAjqtnp=k=1=H^DuGngS=K}CGMz<#MMbXR9ZTz&eZjSS_)c7y_Gc6ME?c^(J2!b!b zNLW}rrJxiRUVF_^sR-5kN_qr3nI<&?qE5@(RrD9XYdRZo8er`ILn*?oJYMQI`}=sY zbq3$PfdeLdaCKZixcYioRxsjZ#C=E4sij*+y`EyZ*mC(sGB2MF_CfhB< zy3njfx)?qeDN~i-RPykbFW3>xGQ?K;x-K7!kmQM)4}Z&oIL20wJct==1r7_TE_c=W zjR>GykglA zHY@3=rfJEQPAb8j-g#rDvP6cNjmZ#*?o+PyO#PGe$wHlu?P`;qBMzrP<7Y~&c7gYS zFiLIT#LPrr*ADWWdlOka zUFcW;rDNSYOjY#FJ~1puRG>suFNr?TgN@>@;)@6`g}s z5p`I+>t<)8$v}RXym$)0pcMj=gah8{BBom3AH3?kItQ18Bb&Xs%G7H0ZmZ%+OHt=t*t3J0 zQrKS8S%%mm>qc5$=tiX)p6E0^RChLETp-sV)QmEbi3~JqlvtZpAS+O8Kp%5wxa2?A(%MRK zsv2jhFsTPWlaae<4p+W}lo@JLfkgm<6_BTuX2p75hYpyd(OIZ=TFw>PUP!a;l06oT z(OXKC5T}LoTY=ZMbdqxtlkze$k~5P$`S~Fdf>ob50Bs^+$u#W&+o?R$gK0VXKP@%( ztXQVF4wfDH{q`|H9$t!VGZK_Y-M1eOmyI$7CXhc`lES))xs)r!R|t!(9SnsboF1b4 zsP*&%8+;@-SgQ7VQ#2>YBOxa00u0FoIlcjSM$ZSK$9M8bjsdQmNJvq~+jxL?Ala-H z3)ebD(c}psiSZx+4(pf z0;X@8bE>uw&Cb%gdj+xo zrDK5AF@PX$f4TGYt3RUd#zZs`?vxj%Z-P|GNU(*{4CAf&o<3jgAh>` zBjcNr%NOu)Q4wBY%u2JL+C(ZQP-74XEhOisjLi5`5kg3_vi$s8hi=;F1Xpz-W8j0trOC|xQh3dfX4>a4b_j8M~~@Qx@aga zrVCH$9KeVfT>)ok$HwQik{Kj?3#<+XE^_t>2Fll!L>yBu-{vYA=uy6Ub?YiOls zyDgw%VRLK%LeW2=1|ZSby+)EW*GeR~9l|3sXOP>Cm$dx{>x=#d%u|fgVp;4$dk18$ zi2AsUnX-5_P81Ya;hp4mSge?5=MbLFTakLB(bv)8ap~!TApS$1t(Wd??FR5Phq^ znlRLjJ9OC@n~{~3anlQ& z()-lLqoH;kIoI0%v$mN4(wdWykWAry+Sh)XGu-7=Z3%cJ07+7iY41&dIuBjRE>2_p6V^F;cSwicuYpb}^>H?5^RQJRb+nrm6>> zLSh-ne9o?xu4dKouNB5y*CiiRtFzCjlNA(06_x?n%W8VC=xKJKTCI;j0xSdY+!Reg z+0Pl6=CTZ~{VR5r=+(tsd$eBz6+K&K-x`l|SVV@#4+>SI>iV4&f-db^XidZA2RM%x zpk3;LW`CFryfRhhhud{(GeqAu+Pw`j4!5~u`!S{i>v7)@9F@eDk4!F_ycJC7x<;@1 zpOuxr_Bz;}omc^qQszYb03&l+REH9eOs7{mn#ki%u6b1u0+hFCnHAx_Mt}?x#G|?T z>EEe2Vh39{tD@N&o=|dOn$s~-jClZl($J^&$Nuqu*oA&icS?#S42xSUfL1`XA+rrM%Tu_YLpCL(eW2rw-lAn2qKls=zaQrUbx6(Aw}4aS5jj;;i^FeN6MD1 zn;k>J*4t~>5#&`4fxWuN3j&=#V4n017C9VFzrT>%1q_@mH`{3LC{#}@Ejk>vH`#>_ z-aPJ>EMKUc*Yo#M@d~=oAa%x%@MXBV{`^kOlc7bYGcI*CX}~8)adCgbav%?ZbWZUNSoW#GDW27t z*AEuQ5Fv>Oo^Lu93wVDF5vGe(1fX^YYR3)Fgbee%D&nzFzJU-|%PY`BXj4F@Vrw3rKy$b}YfX4vw6~!^jj=1an zn|W0>s$mz*(WWzVJ@<9pA?n%}joO%kh9uazp{K$@6M6e~$1@9+TKvfFXtmD-g^Bdj z1D-YOC5w2bcy&edSEm7eN}{MgS+y#cpy95P!>*kN70pKZ`%z~zzlr_5Tu^fu8Lw(K z+76OSXn*)ygT8@BfveeouP)6d%rWrBfXpa767qQi;ch+HBd>t*pAtYL#H)$VVGfGf|pE81nVGmlbxo&=qgxSmH1|9YkI6a+nLX-(X zK;Mk6Vz>-4+75G!1fUpCLhm~(L*8C4K!yJH>F?6Uw8?Tcv~#PYZ6jeOkzj@92@f+J zKxrL+n&kC-tBoIqs~Rz}lJ$$u2!4LfHcx2@{^L@YM?m^sn$BROB5#M(83OL~jo2O& zA9RV_8h-XQmSM8KeQsycX%rd&6$O>6JBZHLoX5LEdft%1wR8lW`N3)Gp?}bu%N;^4 z;u|~ITK@hYgxP_Wb;uYw%hqJ3=oQdzb#8T5mhjP(_hl)eUE5mfnq+-bPMhzLdW4I5 z_~HDu{HIyp-*`ddjG(9B)f!)F5afDJc+CltIIdDde8DI|qQvcD@TS!PI z?S1g|u&l-ejOishA`i{<3cy|<5afBz!-2GW*>ufTvgrqs@!%=%RfU^ZL=nw&ZB<8$ zvC9`vM?vciwFhK>K>`Vbc}OSAkMGzZjawDMYIj%H80Pwhm+s)t=XXCA_43&9pS6g0 z5u*q=JQ#=#aG3PmJF;dB%8U|uk+sTzLEAv+)kkYoWaZ3qU zVIsWYkFi{&k(syhD z`)l^K&-85f;mlP^B*Vn#V0yYXtjOdW#wENt=}czJYwply2-Xtp6rhEB}zd*iC*0B#O|~u z{2UV3w`#3z8G|so3_mfD$vV_6UfcZZ^)BBb&2ZrY$EtIHfnwFgs8vaYN$Ht9PfI z?{C>6`~K&)PaIm zov|Qh`?*5X0%j)=M+MwKv8v17Flfld;qU5?`)yriN9Zz3Q*hr(lFL>7)$jD=_V~Ma zKFxipacTjK!)h^qA^m6BSNgz584DdEQD#zdM^Y`U7?EUp$`N5B=ZvdFYX=vO8h5$d zw%_}7RkN?fUdP631coV+7hRJ*i!AC0Y=Tseu=$HQAQKz47Zu`Cx&-HC{=(7X12EbB zW;*fJvLc7Pf=%)37w&a0N~F~e#612?p>1`cIf+?NZDedumY8K)tK*dubFNZ3lUlO9Wdt!iae3zYt{mB+$L-NA*FzC3b87qABenef zsX6i!{>Pq2p1&>7kt!+kXgTe9#8uksX2(6}ib}{~6*&skTl{nf1%bk@qG>I?Axy`f z)C$Mfe{C8i4nJ^Z6 zrtjx@`4)9G_5m3?qROkDMao%{i=VfKygB9*(0fRHr^j$W{YE*0$_i|C66^)WkgGcp zqbGvh>u%QIl23b@h8qDuh(Dd`ZCWl9MLUc7JRqZ(;0dvM-Tum`U^2C)rk=51Ud?=z zgE049mCuP4)*Q)=d+oY+Y}4rhVTmEag-3zt(eI5Ofm#&YabNph@Kd8bUJ#}Ak25W)^G2Zfl3`#kr*9@Y*wizu& z0&de0d55t&g4AU}c^oIrif=CV^jIoIGk=hYM81ebjoy#fTy=`=pUaU)lv{t^RcdAC zRF93_@~1ZRi-)ehb39nG(N>s!t?N2uc55$uiyU$evOj=r%>}y~+4vil+zkYsRPn>L zqg&&Q#3r;Jcic=1O3#wD;;*$g4y390bOe2zuIStUqAl}Dh7E%F8oOuBBy=S9vDn_R zxTY>epJO6Yvq=KF3hXk9>gV*YxR-Y3P3vB*uJ>cVdD`jR&)dcUElL;JFb|G}N(M9q zoJ==uBilTyMUgeD9XDNi4(UX({(j%pe83jjcOCtoOBf z=*-c)FXk3(53JGexq&5=_4l2b5sLW7?{&8T=LbEKlfgp~a&_-KpK$IS%=Q{^?64@k zB{8n|-F&4tTS09y$dNHG`xuF2aX?G&bf#9+HpEnZj+Ns`oiSfIU@-7&k4#j5SrW|SJ>K89vMAVH0v>r!BL3`GymbUaTpw1lIE!3CJA3Uz{5`Ag`zKMoL=-CFwOQb(0y>9Y$ zT5(@z4SHU>9DEB!VcI5e0C$l%e+n)O^q)vL*U`Ggl(Xtzn-}OLIqJbFO7`Te-QQF3 zL(p*^zIi3T3CI0Ta&PzJJ3DUNjE86IMSsAU!$HRm56t+`Y%R7E?RKR)$@qh%_NEDM z6!F}l7&toqSMN3m-u}vOWFCSFoh$R)XM8wZvd9#>bvfbED(r>6>QsR_Ck<6af6&oM z9#WG0^Ec#t>1hWUdcB#AeE9l<$%s%~yD@(@Qtwmg%gd?wO07sC*h*T^Hai(3J2lHu zwTt+tu@Z3K=*3}DmK%KUQa|u=ZZ*M*WV&v70f>T2{0WKR)_cY{1`~INz)zvf$!n63 z{pj2|ln(mD_6H}?5e}5mE8f&`^?rDaDyX@2$({37PmJ^Yg(+}pf=;@3L*8`0_eXyA_ZC2>dQV7?TxS;Nu4ExTdO=4uBbFj%fB_~cXm2I za-wSB+p_Sw=;~CD*Nw|`2*CLj^Qy$n@|m2`Ra9c?iqYJz2S}uh+C$I<46KFBBa0%T zCa8Vr=`6{cltC15(q->-cV=qNTWMDEWm=`0YZ7^<+Y*>FP1(ro;+mMKe$ac^iiwVO zKK>Y#%{37z_R~x-2QoaQ^s?E0v#*J7X9%>~iG9r;aPt{BqxUlMeQiUQS z>5V&T(?lOfEV!P`XGt8H%ltt%$dA8$78Ay)mbgc{T^0gv`on}B$VWFuRS!0Xh7s#1#K4a=#@ z!~CSOh?^@f$ab6;V$Q3Y)shsC&SNG_H&yz!HJ9q3;s;_x+Mwz z5W30P7=OySnpMfZ$AJ4WeGVwruGr<~#*GPicZ7^KX$$L1jBdDTn%eBx$9u0QS~r)g zbYonZ_pWOd;>=9XU&Ng?{xmCvc{XiM++8vcu!Ac5%pfe{f+UKw*a4Xu9YE#UbGiD) z-*;FctK`aq#VJ8-DM9CqwPj?izJ9wQs>&Ge)MM|)WBtQL*VZ|21VF2!t$9s%wg!q+ zP&PDEv4f68E_CFZ>4~C0mDR|i^_CDd=PW%#irT6oshVm-QIZHgDl?FM2V(cdXrzd1 zDCSFv4rmByvVv620f*;#`HPo>v-Mr06>m`=70ZE9$Obn(h04l8F^K~=3d~*QoxM#{ zmu1g`?4W>&K&8LFN9T-!lM~(OKeLS4?V}%51G+kF!b;{@UXZ;6(oJ3c31=GR7<6hI zSz!^C1nE^J_$zlH`&3Qghr?!*8&m5ydLw7~3w1k*fmMS-B{SrC$T0=lJF(x%J%#wf zk)R}auW5>(UGr}?mCMBwRnBu3=rhVd@DFX1Xk!~h>@5D(N8K|^(WN}ek@ABcf?BU9O~}>h zplllNY!GJnX7{Nu9NEO_ojzPE1*du(q$(PRbh~Lm4f-EI$}F+S5(7?MeoZ=odC&tv zXqw9v{m8*2`HRR(cfa$p_=Lv8l^jW@*1Bbfu4|%?d==TE?{ARPx$$P3>RK{w$w|WnWt!ytP}|W)go@4@EcFxZJNkNRk1&p>o-UH#TaruPTk&&_Z=OWu~>2 zHS5j?5Z-}u?aa2iP7*m%-S%b6w_Yev z{Gfk;vumJpxCPiZQfKFO#EXO-X}kHE*UeUKrm1X0rl!Jv_Suiin1k)6cB&-kB-eEG z&@&DLoTd!&O0qP^?Caeiy%oy3D}JLRzFwQSNLDrxQje- zn~@TUx|E%(x=L1(xf=;GB}`|dK2_&#%BiHn3p$zJSMib!u14=_$-ve3YEhP-6%95{ z8A#<)krY!YPmD6(dkhWhw|u4ScP75P8vygM4|j&o0w4xsfiK)Ymkx?XR92>w?}7FX zu8upMz-5P`BC4Kw2U7#8A(i-lakln*E4q%vzs7IO*=Fme_ttS@{gq|brF<&pfM2L? zLjqaeW5WWpP({?dSL$h-Y1aK5hb;!nr4-|FDjy-9i;j?@WVXR%Y?rAda`~uB>9^c>iBCnBYg7QEyS9e?QK)tqC_TQX^eNtudS0>4 zY3rD&%tuiYa~@yjSL?IV?QL}Rk)}e8H_6Xy#15@Zeu=;Bl4W$NbX5PF6Y{LG#zoq3 zWzqla33AAtJy|~QZBQFWNM!Yo*0kpSsHII<^5Iwe^AG@VxE8y*O9~#vQlF(gAbVt zVA4mV8v+DPN^WQ}Dv6yBfhS1k|5o3quniZHA<|>8Vd?+LDae`8d^EbEFm}0r6y6{l zu9#PkRf?~=PBvr6;9_XPXvrJcg}VC8-%j|{@AoyS&O_aXhJTyMO4Z=p;-MMFexhN= z-(D+*)|XF1nMd`5>MtG&-yB=HkX(OMe}CJo?G=f$|M88dId>_GN$L|X&aa|8x+T&E z7L#*rMH1qu-L0K>3TLvnm8L#=^_{BQh?%PU_MC>x$^*KDU-BYdX~8Gxjt-YKMw(o4 zU$u9CVT0A&f@kn+EgOvP972Zsyt=m7Q!dX?*lFo(aQ^d9-JRu-VrDP4qUCv?IrUiCfa4dcsL;0bbyl{{4! z!pNdb*g-$mA|XLC{CL78Lp12mxYXxTIn?y+-e_w{F%k z0aw>>GWM=2Xhl6yu->2m3-&UP3jgMD3rF=u4Fsek1{8Pj)w&(*H;YWML#hR6?wP=N zKT-UxyA zc=m(Fd5P|`D>Ok>2hCk1*g&4ZdY%Fb7>ma1Z(WyH&A;o3Zb{wz;T6*RRM{2$9(7X{ z?~;|3kBt>zkqtaQ08@CvbsrHPO9F?MKy9669+0)m_NtfTq!VCA{NUW$ieO-$a~@eWh6v zn>})8mY^p%%cHCD4^{kU8&6jRO)#R{tC>BO`VVJQ(cJCvDcJ7RG9!`-x@R%-TI$B9 zKQ?7#vHVSw6C3;0duii$Lr&B5y)<=Px1<7jY!@r^UvR6$=(b4h#xfEOl~hmk-l!&! z;^H}Mo#zz`k|FBxA6kMDQt7q%EnW$Q-$2zYY(djGcxx4PREU0O-Gf|*;(&7J4AgBu zDE^0XuHVIF$}YeVHJM<)kLEq?qLjy?x<5ERbg0yENM1q}`;~y#f>X2nhrBV^Cib3W zL4`d1KVOnHzprqnX?uwo%ps48x|(C5+Uweo$i`No*~?ls>M(0>KVFw@s;<@4A^V=H z;Cuhfi+NT+CImzI6)*ot|Es>s&c?a-YqqX^rfI&{wZWZcn=YaYlXJabZ(&;ip64Ks zBW6Bo!pyqp2piSICwgdZo;$=I7%5pBa}%1h{O1xc_kQma&=mI$LXr=*63SHUYsV*N zDoPE6Wn?X2=$d2k)>wJ^8r_e)*^l!6UQ`;IrG$KU=M9mB$<=PpEVTNBb*xPosQ|Ik zl6v)eVYT@xma4zZV%P11YNc_f5-VBxJp0T-6vG?8s~^un4+l%|ng-;$FRK?MR-)9+ zKFTuM3*dH=keoQqVe9%q4Q#veEWl0(1M)H zYNxcddDqU~ak*sdy+7Q+=dsjxy_OTO4hJzRG zKD6}RVfmF7U;WGfM8Da;G&kX>sFHPM{JKJ`M6@VaOHZq~j9;E!g510P)IHTD!0m{j z4hzh1&+kVUNt=LGN0UwX?KzB;tBf0GB^C^V42{Ssv9PkPpB#-cPqzq<(fLh?SIIaj z_|R}+Psmls<8b&sZ3%(1UNO^LCnCq+e5co|zR!B+m2%9FwoOB;gc#%tyz)4G+mBp! z77lw;Qw7n%e~8*UIT=L@mJFLj>ILS@N=svkSTVJc^tYru7Y<~iCM=GvT`^Okw=3D* z$=w<)pB?_L$}lF1zt*1&1S^awJi)tJ0AYNsj{@iMv~#gU&FpN-1a#%-46Xm1VeCYOLrOFcW zH5tRCa20G6D2W-UsKs9eBZ4ix%L$BYKQb1O7Cy(8{W|aN?}-?Gc|p}P?eGpyJp%f~ zu{iW!YN!*`3BUWD+iWzd_fIGu60TQ#21I&<$rMZDn%s$r4~xCSG)+vDU-OW#;ONP% zX+k?(PPMiEbzqLoqJ_+>u=d9frA*c-_^|)tai>=1Jq#4n@NPZ0Gh;IJ+Y|SvPsr!@ z_tf!^>C20zqW^`2|034m%lMABf5(Ncobg`hzd&Ewdt8qmOXYn0{d(q6`@fiCT0;3? zeExFA{~ELE8AdOIZ8G@YZ31fz8^W;3@9#5V>2E63pFS05Yh|GN=?~re`=wns;SHQt z^oKjUKRdbkdJ_a_M3=2o-x-wTh2Q1x;o$(*&#Ncj z@xuspcdjJ2$!4vHo~^(MxD|~q7*@L!KU{5T%jHz=J`r?v6&j6dOL5q@P4&L9I1$gN z{1WH1bIaw;_Ue5J05eCCre&I`DV>v6O~gtXC2n-V+iYBZ@9~-x=4OS&u}NqFu%^@!xQPY{O!h{N!vQ9Q-)do#T} zW$$p9eu)@egtI9fjGQ#Lqt=@Ag#$Nly#S-FPwwyF^!H@g1y9QU>mlt%e@l!SyBL!c zf0f+%Qbd#z#YWhSk1clA`2$s44i^KMVJ~|1^$o1WfBRhh?9nHllX}gqtC9O9zd)0z z2Lim&wBVqTaKHVQNRX&EJuA~nxgpQidGZ&{lP83CzJS5Tw@G@ww^fK_W)1NE8(zeRWe>Hxdtau97DB^k5 z;`eR4)b&n`)Sy&6UM}_Mi?FYSyV4$+Q{e7yeHdqWoE@=0qt);s!PZpH*XE0uloG69)ywQ%6DXp6HztyuAL0)N6ABQ@Qt9g2I@2nEnsVYoOoOgW zDw#?i=;?fImm+(CYZveTC8_p$Jvm-}1=VO4W^se*-y1E@aICOTYIAXMF+V1k|MgHA z*NO(g{~L6~q&B3+l<9HQf<>zNlYgpnN%r|2JXK0MI?jh{+C#WjJh769`^EcjlYjSI zJjM1a5gH)hDe~oCEv)vtC8b4jc}jD=ja5rpF}QYT9)11yi_I$jzk#BX(xM|JoSdGv zj5he%E$~lswM+e@<-{gfDwy9Ar+Q}S{+Gx5-{s?(cEOX<5)l>cX!iP-oT!}r;^FP! zQp88}ZSu$=sl1TB$2byaZv8*Df&~^3(9zaTPAGU}G|Klt7WavUKXxkfD|D+3{y)yk z|4H5(27El*%2<%&LYF%=<1bcu+(7mT|AXa=_g{0R|8Hzyru|aP-tCZJPHUQbJ1MxY z%ZdN1qQ}wq-!IPNhj_u(hCD84o9Hy0DZ-nf^usMqTWf3jdzB}*WdCJ$lA?S5f6xB( ze*ry^(hBVGOL_m=0=qWmg!wP$-oK+eAasfK`%qlQ@{q?d=vIilW_l)ta_qu}#qF`v z$!?h)YpPpf-2W!6u&C(n?QAw0HqA~fGY|U?`3cx$&DbSfBDF7<1r|C+r{K7As}qIfJ-( z7bggL7XFkXyAJPWN>}7)PGSIP6X8D* z-j=zI8{!yth{2_ApFPYkD;uP0co1qAW?1HfG5V`@Y7xrXrUEj{cxv~rk+0ZBGTGK9 z@Ivrx2Bzc#AZz4ySeQfgP{lU{%-EI=ag!B1@R5^bVKb?s+9`ZWi+8l#Bt}~vOPq!> zP6y=EENojJM6%AzG|KFaf9~$CTkXUHs~GU|*V)i05=0*~QpOq)WUc%fI~TvSa7rimUgcFp_k~y5eYxxV1Kup; zPjHf_!SL^^7i_EiU%$5Ly>8Fye}IUM^pnDsssB?oa&mGsG_-a79KAeuxF6}NN38It zcABsy=SEt|qvQU$Q8V0Fftl2=4S2zie0Z*m9W352{{JxT6J#YLa_1c%MH=^~0rdDm>~rjgKB@o6cS2c( z{?B<6pcZZ7N1p$@FL(F8^@-57@w0!8U^##!ve+O#G6~UG_owI!()?COORgGMxjQA@ z2p15W6+_hUe#)LEwYRf4RjOt&n=tkc8dH$#tVSghei5{g*U@sXgyJz?=ff0ZKMBUX z)773Z7Mw36=Ksc0RN&e6;lTL8@pm`J{=%&)d^aPKyf<|@<|b9U%_qJiwH-W;n=R*Q z2c0#L*@@aJd<-li&I!IABoWJyz0~>nPYX1Zc=<~085H}v@T9YDU}FPRDv@#TSdnIe z4{t6rHDrxSi#OGz~ z65v>Rg7{xoRO7lmF=1iPW`B(r{#cG|lgXlL?rGP4L@Vs|oq`FX$W0?*_?er_z;1uC zZ}(5=o>+UgoF6Qs`#J5j3Ot8PW20~N`c2% zTabQRAn9J&tB3nfpL|A^YckT^kx_jC_xO(9mu;t9N9kVcOkaqvm zR=qK2W?s-=+{&#I1m`uz4EY}n-_~Csh%oW$dxq)I_x$CvMhzVl+lp;A zk1+7lHnKki8D#0&G3E}Rm2MY=B)pin>JFp}mMVX=kZ^P`Zmv$jmzSd*5J=T%Fn$k+m@Qe0fb4Cf!UgU;(%qiS}2<|olqZp>;N8DfBYNw^ zvF_Nz+&j*<@O#E3!8yzT$0XDQI8VFq@9*e&Vp=%eYFl`l9s9(sz(e<10y!pX@piMp zDTnPZvu2&My~bq-ws6-S?lR>ivL_4UQ$0&gXv`ER3KWjj=vJ~jd@l2@ zYg|}vmTlq&6^Zb2b2cbf4>0%iUMCKx3k&gs!XIJzzEk6W@75ZY?0Wr*Q}uIE4cG|{ zdUx##a9Q%;UDs?*Ze$P}3ulNbcpte?=cm5b_42`+85QE~F=0Ld!;|jYU+(?z$>NT6 z)&su#{+#l`l3@UU3bwB`xn5VEnFI|z6>j3M=A+dd7}1f!))YBcuUqb9?$)%~*pMet z?<0YP^amF-?>VGe!E#$h-*K zBF<6}j zXft0o5l%~CVVbZ55KGzUva~Jt4=+qME``*N#tPs#=qt%Tdwc!hjOKKk@C$W>AQd%% zDu9nm~CF5mYOGTDt_|yq9fVMLYXFT(XcyMRM_OYOa zH9JW+focs}iopkq1Akd@hD+cMj*1!5ynCUgNjb$bdqC(H-j07I_i^636z5Ou*(8KN zR|N}jE=7waeDWO*l}^?3&2uSr^>~~=I!%~I-mI?d1<{|PPT~F}AvzQgh&%9+!pAzZ z!KL@F_@$oz;)&S7qLp^nJUx5&g5Q&26M#z_DaDU-ccoxaY4D=Exs*|#l(xs{R6ahy z8ob~EocA1TPl1uhly9uiNH+QX;41bSPLC^N##w2+CjGz{{f z4z^f;z7&ENThp!bTazW+7H!#FYkTmBUY7p*gtE;P4Iu)6wHXu4SW~pkIm*_ zOQ!GWk6G;h%Z^(^)BCvb2D8+0jxL%FznD$-~y^EXKJ;!BGHOnQ1XL3MOm* zRipI(m_crwzk}zb*XjL$#Isf-+2B_vFtRO44*S)~2iycsn*OLE#Z91Br3P(6Pdr7} zKZZG}|5y0oM_szOScs{UVZp@-i8a`{^yfG1r&7fKWM}DWPR&p`*o@|;%ixTq z@C|#q?{{212b@Q0OE)(gr5-9IkCm8`vUF~BoW$6Y;|M$KxpeM6@{f+`!Zq?^g$ zxUTU5mLG$u%y)ppL85C||M1F-d5syj=9f5GoTTcTqkZ8{XZRls{zQcuYI?4=WZ_j{8uap0|U19hds6GJH7KJmDd>QJMV_006lSFWFo+8C-Pz>&5JVs z1(~TK_ZJLsu{=cmib>l*AT*IpVrarQXlZFFLocwKzUJhPZrS~lwUy0VggAa0V>)^P zSOFL}q$LYEAERvhkE47UbzH)}kOT{bX%RwNH&I)t6B@*Z+omeULV+g-kvY;s)GF+c62Y}- zK@Lza2z=<5k6m4>WLa2>yH#AL*(vkG<%2O6wTYt*iFmjd_2xmGKxUh+D*k>Ib9F@l zqF%&M&{+UC5|K#>0K7LQ+k#HKyW(s&e~RFa9YP*DOCw4S5(fKI92Iarlh^$aOCejF z8S)pyWn6ZOVkz!0K}y>k$JsvXlg9089yRVH1p2&CY`zn4*=CkUQEy%pV3}-z8zwyw zGrbP&orGZEOn1oE$;Oq%iB~Yr7a>r*)~_5b0@k7MUG^qqYius=&#tenzN8L&^gPM8 zMOX|2$vJZ$Iz@2#t%7sAbA{Al?=VO3L=FG>>3K&q8j*J1qdg;8Y z4>Uq2mTu#wniVUw>TznE8v4uN69goj4d^=Xs_yr2JQvJIAooQ@o-k@=a)4j?=R$yR zO4tr?(dX*eWJYAsFLFdE^zia)dh)130^)Uu{(_o4J*%VwE;9t?3IgLjS_5n-P!* z8wG*-G&_x`wY*^6*>bj;n8!W8hHIlMvKHB2@D#oRK$hbAlS_(_k!*E&3ASkyugs~w zvY`vOVI4vF8lmq?kmwh@AiLr@Hx(>3E$|!I6+Y9(T0xz4X!BZKaNBFQEWoJ7!G-Tb zcttfiU}D1T4O?>6Plq-NT)nC4}7WFGmDm6nRtReqcJpw8jXpe z{rmnh{>OH1j29aj0Hv=sOt-0U^JatWq@+vy0oi&p7hNq*7{*tj2du+y(Nxk}J<=Q_ z$tesVV9sCxefiTuMhretML%{P?;MVsBBTCk-o})ow$BAD>F@(#lMIOX@~0((jD((9 zgG5;fS4^n!k(|}(W$bTKXw(rHZdA%OK{5B?DL`cOdMEu_#I*>rP~^WC&i;oBkdtS# zowQiWmVWB6o44Sr+qzzy8%GLg((a1z(v6<=sJC+9f3lrv2GPNmRPi(HaL2iW;zgg? zBDJ7{E?l$KYD#9N+Ffo+Oq!d0~rXULKfoHP%iRYV&;PGmJh0Ib~CB{ z`hx-8+EY7YkUPLZPl>eY!>6WU6RoxuCx0rmi=;DJ738EsvNj(4vQK@+voNrSGR#5f zB9vfz1&5z5!<*%U-|b4G&z!*Re9-ROC=n2h2>zI=cYFHYPv+U#w=eX1wEd`QjwBJ9`iY~GgpJ_!~*d} zf3>{Xijl?t4_kMOps1P^@CbJE;AreofuK3<{-lf z(_H#}%3~!V-kUeAu!ob3l$2C4Uv;FljF0(Tr+K*&UqxAs9r4SuygJ+ck}L;{mq-Z+pFEXC1egsB3^LrZ+udYsem%-@Oh|}#j(xIoUOw_;Oi~?`l^7KfN$4w- z3dNIcy2}#u3JrL zt0*SLswJ~&)+eb1q4KdjBqWJ1UZ{RrKoNWlQFy_@$Ib0oE)@hK(ddZl_!_~O(&4g< z6HfL+@>g%@sc5jY3&f8riM2>TE~Qd12#XF){3v$~UkcCD7-SN&xRDfTXon4eSzW@z zy~NQs*CJ6owaloE84+x(K^9ydT~rb#eEsI#f-!VbjxXXZN~uNJ#lTE^s>#q&nOaPf z)Z*GwK}<=9qKf{OP&^~UlTu|KMK=$ z?&*nFBAN9Du)UqzM%FN1%sqLFLUD-Y3anYYp1!?>U+GZeU%|0Gj3Q@g?|9$?pUJn~%P zNOD?Cs2iJ;dNrXC$Di;caQ6PI<)z{kL|szgJygfo)P*=%+=_LfV0Oaveto4xx1>f- zqetS=$`we=Ho}mzDJUZ~wn*@n0WHhGs?*=64kUd`bGjh`G+MJrK59_y)1o zP~4-(L1k3$`DXQky?qB0!^3N9H&BiZY>5@o(EN=R!J0Gkr4w6P@0kmaShJMx?oO5L zuQ4z8^a1vE2wb5G%`Fs)94LPN8X#1AQQ_Ke*|v)hdBV+Y;zGJ>Y+HAeaCrE^q}8EYnTbnSK9Y^y{*I7QE6QFt&zu4?zbo zeJDP!BDLqUdZ?B)q<#aXm?MJkYjLFl+8o&wD3YQv`xS8n|6#6|wcDd^wdRPHRmMFD zVSuXhUwWfJtTwRAiz<=4u6tDp*96_B4WH;T5d~Zz;qgU|n&aT<^ueiiN+lDm=9r}N zj3erV1n8H)pu~`X%zia`&BT{Fj3ho{;{nzaj#DNfATrP1a`xHjG>aQly{L#`ZS2f7 z+>#vKT7qa{vhCgcp1*qG-0?y_qU^Z(1`2RO7C5#4$S@;w?Qza~qg3tQ4X8f|XxUtq z_nDmXpBT%z#hWX7g*bIB+>!)bSoVB7vAe$vDZbWRn^)=*oUE}j@G~WGToM`#hC>W= zT#7}iA{c7QLh<6fbm@LU0CQgkwgPhwLA<_xIbX>T5sPAgT<6F${r zWJH$qm#Ns@-=gn_=ND)w%E=9QG4gJ|zD8UsJ~b%YybbMztR*l6nTzIhlTDl}395m; zD^w}1RI~|cGU%_a!Utn{M+TzmOw`Yl$|Cu`^|(mpX?! z?9NueZ7kYEYpwg&ja*kIBPyf)Zv9zG?8NTiCb|j^glxN|lcu|bM2NZ?&q>^^r}wr7 z{X>+k!z`j`=I?AhYx}wsyIo~eJ4W91rt!73WEa6~dF|hPD<0sDWbrvE%FwZxFXYS> zwd*MNi-dm;pZS9Vm`jni-z44dWrP@Yi!S*_rn?wpR83M-)&EeFD(AJ|2>+Xa?t|bU z12?`DKjquGAylkk+xL29`SAYSwr*ov`Ec~kNf5aUYGrYnGx(x>7r4$Gd{%+hgJG|{ zo#jWx?{5#%_ZJwPZW#%CO$*nv;Z(v6+P;@JGQK?t!$f>)uKxV3c%XME*+h*?fRVj` z7o^dEKq1V{khk>Q=Ovq&ZCC$Let`d9h7vclhM?#BUK09mTMytSIFyS81VO`~l6{cA4qaXRi_luCEImYBy+Cyt-Ftr)#Jwv-C;0+&;R&wo!?NBDej zPOSod8efRmvSW~;#oIrKUP}(&xxuR^DFO*}azk?liiA>kk<$f}& zUuLdh%kV;1?LseZ;*VQ_m$AvzHA-8e^sV)-@-sAFu$!EouPis>d@ox(5GFOF2Q9^PM@nJW|rOtm6b8R`>fJJs2LQg$GHMrY2OV!G2&FuDdk!P;93~d=~Ta-n)vA zq-||@cY~*LwJ>QMCEhW2A!H59y8w)UjqDUt6fiG6P%gC3C7|;q`Rm>utEV@6y8-=P+YkY(u^l*d6uTxpkQ zo2~}C`%fi?QM8Z#Zz`~j=7cBUPW&nXSg$e1q*4b{vTW(CLPTqI-WN*r8)F9^%|{uYQpRSlaT0ZFr9E{0x?fR{QHNFJdoK_KN zb^?UJy{2!!e@jEHA~0`3_^0a$HRSL>?htwyuMBXb%bI!lw!s)mje(vtH8b2BEB@l{ zVa6{*Z^=?Ys+U^D!^DDX-Hd6{T+|de$*eb*xq#~h7K$F2QAr(#4Vtx=&e;NhN?I|o z!nS=jmNuXGd<&F4Kx1W=JmWhL8z%Q#Iil1|SAzWU1-lH0_JJ*|WC4SbPPrdvy!PGa z1{F1TqVn%V{5Lpt6~Kc!Ctouc*sm0WDAFD9YPYv?P?wtlz-Y9J==|e(3~UD&QtMOq)?p~Mc64M zeX8~{78+wg0q~3d)&bQbR?+I{Np0K?Dz4qbX_*ZRWRp&}64K9H*ueb)+_Nr`NmU6N zG!Xp&f9ij&}j-;8k`seps;^bGVqn{9tBk{cA$ zxpn9>R`{v=2$QY1@Y7X?r;`GbG_)hgj4ss%WHDfwjsygt5U1!qrKqdu9X&1X6QRSp zoV(DBJ&}N1^w+oW(XVWY=5nr+Vd?A~$Zi_g_=GzXa3YWu=7@u9qU)(lZb7P(>u{K56!=}>ve)I3s1y0-W)Aj~2 zWs;WEf;>&?SsHnCaZFaSvE`$<5YJQH?5OEHDvy^Z1=Z-u zbx#)CGoJi@`CDLqsHdLV6)rfM7nvI#`~Wa8x7J6eA02Ouvg?d7XDc#Ye697_W6!Rn zf8vc|#=I9BoKIMM?fH*4Qr-N@k@_F>Rw=c@C6c+Z;)F84jIvOq11G+gzGOMHtm0hQ zuE7+X;<|z8kt{eWxH4Xlos~6&c}iJ9ua?p!SoEetuvrMs)~re=eMtX;7F7&+7I zeMljn0>6-)qG(P$s7|@EvceZ4!;BCq}Rz3k2~b=RGP2v1N3|HAA&Z!h8dg9{Z; zcICvPq7d8^#6h2%0^#KIML{#hlz=>VpIK+i@d~gRZ$PtN5eFz~`hQn^Cfw)?n8Cx0 zeoB}X-|WA_mgS{W@&&=;^JlPTtu4)F{W{-|rQ$m--N;%Axu<=7mXcrR$`e=Zg3ou*QDL_Hp5cd#vE;uwMtHgqXl|i$A+s|(GiaAj{QO9a-!c{LwV)fx}d z{npzU0Wry<4~Zbr>LjqRjdPHj5iAsP?Qfjjz9ThdS{7BCvA(?*XPex9PBhkQ^VDA} zvxu8BpqxL-WY+MVnNJZlQbXh@aq8{UVJ8wd#I>-w9EP7;&U*6cc#;e*OLqN}3Zk!w zyu*Z3{mm?0Xe|G#JCEvLxAix!R_bF1`z z6Oi&_k7P*y%Mbhw({SD<=bwD8BULJTQPljQ_dB|DI8bNrwTpZ6G)D_rh zX6>q6S#ApM<>P=v=BW%CZ6qdj2bj`jOGS&J)QKNW5}qL)Eofb^1kNOLLf89(x9gSa z0?)S-QlAK%esTGqReIzKX=@W*4H@?8)IgcNra7?T?Bw}yuQ-3Qo`U)l{YAk5(i@pt z>M6PkvHA&GaP`OI9bDQ7XI-iyV(#;%8LM#2qWp0`S5Oe2-n8^%o_mI>azz>3Ou zwc3FHYP7Owv@&k|R)=6yjBMv;MW;55tC=nL%n$B!Hq%p`b`f zWSG2rucvt9X5(5IY68QT#(}?wLRcp*)m(qlzRU2kAm|E>hRkt zBDrhE+52tX4SHDSvj7V5W^^~<*$a&y<@SzgjVz3!H^Is2B4BlWwnEf^KB5h2s>e<$ zlP*2GMGQl%gYTcLlr<$c^VIi0sN0*H4Wz!wj>}QuWT#;Bau%QhGzT_G7og{9@-(ZkVhY=u~zkS$ajxCna*r zdTjZm^gKvqGT$Y>roNmw*8WXqP`zKL+Xda#O$)}Fdd(6P#s2hAti+Gb{hs5=Lb$Fb zGo#A(iWgu;;#q<&vHhy@NtWau-ybR-Zek{S5Y?{@^(O~sx2JTs#tb*C1EfF4&tn;oUwv23tG5|lb2`% zHWa8M^lea%Z_^n2_gjq1-=aGkj7dOH`ILYaRRBL+fFG?{SxEkDyS?)Z{CNH@jsF!? ziL|sjLu!h4QD|<2Kp{ipY8Y>6%YHpL6ifJ{jzc^s zC@d^2sPCjRf|I}yba#n!INb7afumChCnm9j&db zCz7Xc*sBqurl!6GPAZieg?d~iKM5y0>F{B&^IP#6+-$bp4^|dk+Vdys+~moaBt(6&IPFMe2{M0E zzaC>{L>DzDP<#5zWGnmk(iNcDvi+1n2rA5+(OBbRR=u}lS_}837c9O_qF`KJilC8G z%*%$Hy7rIhMlL_o1fH;46Nzq=>s5+-tfxK#LZ`Y%At#~Q{VT)j;sqm*8PAA>!Pnph zx2bn}m1ihR$1Xe=cPdNJK8lbD#YIN)#pz(M3TY&1ZI`+ScqD&qF5;}&Y>jU8e0p+9 zvmv!TR|l=kML<&@6R=hVj`OH469(;&_ZMgQQa@}ICkJy}NdaKKyr)(1NyFs&L+;;hK*rW<2p>~hgy-4V4*b>y9H zkwAi`4eR4l;nc#Qs$PzW^PX%jF_u_OV zSbhII&LrkDtm5vk_-i#B^cj$zcG`h1^O1qM9q~Vb*>fd6{ctIT<~l#|aMRh~u*kff zxL6(_6Mo2o9`zm6rhD!zR!1lMP9XvVbG!D23eLesvcUcneJBw!Jbd{@o#3A#gS&BjnO+rhlhK5bvP&!l~uxaI_95UAscNys;rmU`fP<0+8X+1U;BeJCYE d2*GfC*p3QH^TSTO8TbaKtnlDoiJWP`e*v?0b~69~ literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-lamb/index.html b/apps/website/public/widgets/nn-lamb/index.html new file mode 100644 index 0000000000..e815e8a364 --- /dev/null +++ b/apps/website/public/widgets/nn-lamb/index.html @@ -0,0 +1,47 @@ + + + + + + +LAMB: one learning rate for layers of every size · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/optimizer/lamb.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 21 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-lamb/logic.js b/apps/website/public/widgets/nn-lamb/logic.js new file mode 100644 index 0000000000..050f47f582 --- /dev/null +++ b/apps/website/public/widgets/nn-lamb/logic.js @@ -0,0 +1,48 @@ +// Generated by scripts/t27-logic.mjs from lamb.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 3dd28c18f0aa03e48a900bc0a78a02bf8a54812f695656dd4aa3c0f991682971 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-lamb/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABKgdgAn1/AX1gAX0Bf2AAAX1gAX8BfWAHf39/f39/fwBgAX0BfWACfX0BfQMLCgAAAQIDBAUDAwYEBQFwAQEBBQMBABEGCQF/AUGAgMAACwd8CAZtZW1vcnkCAAh0MjdfcG93aQAADXQyN19pc19maW5pdGUAAg90MjdfdmFsaWRfaW5wdXQAAw50MjdfdHdvX2xheWVycwAEDXQyN19zdGVwX25vcm0ABhB0MjdfZmlyc3RfdXBkYXRlAAcOdDI3X2luaXRfcHJvYmUACAqXDQoMACAAIAEQgYCAgAALKAEBfUMAAIA/IQICQANAIAFFDQEgAUF/aiEBIAAgApQhAgwACwsgAgsSACAAIABbIAAgAJMiACAAW3ELBwBDZmZmPwuSAwIGfwF9I4CAgIAAQYABayIBJICAgIAAIAFCAjcCRCABQQI2AjwgASABQRhqQQhqNgJMIAFBAjYCUCABIAFBKGpBCGo2AlQgAUICNwJYIAFCADcCKCABQgA3AjAgAUIANwIYIAFCADcCICABQoCAgIKEgIDAwAA3AhAgAUKAgID8g4CAgMAANwIIIAEgAUEoajYCQCABIAFBGGo2AjggAUKKro/hg4CAkMEANwJ4IAFC9/z++9P3jcM1NwJwIAFC76SM1OPMmbM/NwJoQQAhAiABQThqIQMCQANAIAJBEEYNASABIAFBCGogAmoiBEECIAJBgIDAgABqIAMgAUHoAGogAUHgAGoQhYCAgAAgASgCACEFIANBEGoiBiAGKAIAQQFqNgIAIAQgBCoCACAFKgIAkjgCACAEQQRqIgQgBCoCACAFKgIEkjgCACADQRRqIQMgAkEIaiECDAALCwJAAkAgAEEERw0AIAEoAlyzIQcMAQsgAUEIaiAAQQJ0aioCACEHCyABQYABaiSAgICAACAHC60DBQh9An8EfQN/AX1DAACAPyAFKgIIIgeTIQhDAACAPyAFKgIEIgmTIQogBSoCFCELIAUqAhAhDCAFKgIMIQ0gBSoCACEOIAQoAgghDyAEKAIAIRBDAACAPyAJIAQoAhBBAWoiBRCBgICAAJMhEUMAAIA/IAcgBRCBgICAAJMhEkMAAAAAIRNBACEFIAIhBEMAAAAAIRQCQANAIARFDQEgECAFaiIVIAkgFSoCAJQgCiADIAVqIhYqAgCUkjgCACAPIAVqIhcgByAXKgIAlCAWKgIAIhggCCAYlJSSIhg4AgAgBiAFaiAMIAEgBWoiFioCAJQgFSoCACARlSANIBggEpWRkpWSIhg4AgAgFCAYIBiUkiEUIAVBBGohBSAEQX9qIQQgEyAWKgIAIhggGJSSIRMMAAsLQwAAgD8hGAJAIBNDAAAAAF5FDQAgFEMAAAAAXkUNACATkSALEImAgIAAIBSRlSEYCyAYIA6MlCEYIAYhBSACIQQCQANAIARFDQEgBSAYIAUqAgCUOAIAIAVBBGohBSAEQX9qIQQMAAsLIAAgAjYCBCAAIAY2AgAL2gECAn8BfSOAgICAAEHgAGsiASSAgICAACABQoquj+GDgICQwQA3AlggAUL3/P770/eNwzU3AlAgAULvpIzU48yZsz83AkggAUICNwJAIAFBAjYCOCABQgA3AiQgAUIANwIcIAEgADgCFCABIAAgAJI4AhggASABQSRqNgI8IAEgAUEcajYCNCABQQhqIAFBFGpBAkGQgMCAACABQTRqIAFByABqIAFBLGoQhYCAgAAgASgCCCICKgIEIQAgAioCACEDIAFB4ABqJICAgIAAIAMgA5QgACAAlJKRC5kCAgJ/AX0jgICAgABB4ABrIgEkgICAgAAgAUEwakEAKAKggMCAADYCACABQQApApiAwIAANwMoQQAhAgJAA0AgAkEMRg0BIAFBHGogAmpBADYCACABQRBqIAJqQQA2AgAgAkEEaiECDAALCyABQgM3AkAgAUEDNgI4IAFCiq6P4YOAgJDBADcCWCABQvf8/vvT943DNTcCUCABQu+kjNTjzJmzPzcCSCABIAFBHGo2AjwgASABQRBqNgI0IAFBCGpBpIDAgABBA0GwgMCAACABQTRqIAFByABqIAFBKGoQhYCAgAACQAJAIABBA0cNACABKAIMsyEDDAELIAEoAgggAEECdGoqAgAhAwsgAUHgAGokgICAgAAgAwvDAQICfwF9I4CAgIAAQaAGayIBJICAgIAAAkBBkANFIgINACABQbyAwIAAQZAD/AoAAAsCQCACDQAgAUGQA2pBvIDAgABBkAP8CgAAC0EAIQICQANAIAJBkANGDQEgAUGQA2ogAmpBADYCACABIAJqQQA2AgAgAkEEaiECDAALC0MAAMhCIQMCQAJAAkACQCAADgQDAwABAgtDAAAAACEDDAILIAEqAgAhAwwBCyABKgKcBiEDCyABQaAGaiSAgICAACADC0UBAX8CQCAAIABcDQACQCABIAFbDQAgAA8LAkAgAbwgALwiAnNBf0oNACAAIAEgAkEASBsPCyAAIAEgACABXRshAQsgAQsL1gMBAEGAgMAAC8wDzczMPc3MTD6amZk+zczMPs3MzD3NzEw+AAAQQQAAEEEAABBBAACAPwAAAEAAAEBAzczMPc3MTD6amZk+AAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQ=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function initProbe(which) { + return W.t27_init_probe(int(which, 0, 255, "init_probe.which")); +} +function firstUpdate(index) { + return W.t27_first_update(int(index, 0, 4294967295, "first_update.index")); +} +function stepNorm(scale) { + return W.t27_step_norm(scale); +} +function twoLayers(which) { + return W.t27_two_layers(int(which, 0, 4294967295, "two_layers.which")); +} +function validInput() { + return W.t27_valid_input(); +} +function isFinite(x) { + return W.t27_is_finite(x) !== 0; +} +function powi(b, t) { + return W.t27_powi(b, int(t, 0, 4294967295, "powi.t")); +} +const __NOT_LOWERED__ = Object.freeze(["init_state", "compute_layer_update", "forward", "cfg", "step"]); +export { + __NOT_LOWERED__, + firstUpdate, + initProbe, + isFinite, + powi, + stepNorm, + twoLayers, + validInput +}; diff --git a/apps/website/public/widgets/nn-lamb/logic.t27 b/apps/website/public/widgets/nn-lamb/logic.t27 new file mode 100644 index 0000000000..5d9e8dfb42 --- /dev/null +++ b/apps/website/public/widgets/nn-lamb/logic.t27 @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// LAMB parameter update with trust ratio clipping | φ² + 1/φ² = 3 | TRINITY + +// #8980: built with `append` on `[]` and `range` / `len` / `pow`, so it never +// compiled. The math was also not LAMB: v_hat used beta1's bias correction, the +// "trust ratio" was ||g|| / ||v_hat|| and was computed, then never applied to the +// step, and m and v were never written back. It is now You et al. (2020): +// r = m_hat / (sqrt(v_hat) + eps) + wd * w, trust = min(||w||, clip) / ||r||, +// w = w - lr * trust * r, +// per layer, over buffers the caller owns. + +module Lamb; + use base::types; + use math::constants; + use ml::optimizer::adam; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_LR : f32 = 0.001; + const DEFAULT_BETA1 : f32 = 0.9; + const DEFAULT_BETA2 : f32 = 0.999; + const DEFAULT_EPSILON : f32 = 1e-6; + const DEFAULT_CLIP_THRESHOLD : f32 = 10.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const LAMBConfig = struct { + learning_rate : f32, + beta1 : f32, + beta2 : f32, + epsilon : f32, + weight_decay : f32, + clip_threshold : f32, + }; + + pub const LAMBState = struct { + m : []f32, + v : []f32, + step : u32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // m and v are the first num_params entries of the given buffers, zeroed; step 0 + fn init_state(m: []f32, v: []f32, num_params: u32) -> LAMBState { + var i : usize = 0; + while (i < num_params) { + m[i] = 0.0; + v[i] = 0.0; + i = i + 1; + } + return LAMBState{ .m = m[0..num_params], .v = v[0..num_params], .step = 0 }; + } + + // powi (b^t for a whole t) comes from specs/ml/optimizer/adam.t27 through `use` + + // Writes the moments for step (state.step + 1) into state.m / state.v and the update to + // ADD to params into `update`; returns update[0..n] + fn compute_layer_update(params: []const f32, grads: []const f32, state: LAMBState, config: LAMBConfig, update: []f32) -> []f32 { + const n = params.len; + const t = state.step + 1; + const c1 = 1.0 - powi(config.beta1, t); + const c2 = 1.0 - powi(config.beta2, t); + var w_norm : f32 = 0.0; + var r_norm : f32 = 0.0; + var i : usize = 0; + while (i < n) { + state.m[i] = config.beta1 * state.m[i] + (1.0 - config.beta1) * grads[i]; + state.v[i] = config.beta2 * state.v[i] + (1.0 - config.beta2) * grads[i] * grads[i]; + const r = (state.m[i] / c1) / (sqrt(state.v[i] / c2) + config.epsilon) + config.weight_decay * params[i]; + update[i] = r; + w_norm = w_norm + params[i] * params[i]; + r_norm = r_norm + r * r; + i = i + 1; + } + w_norm = sqrt(w_norm); + r_norm = sqrt(r_norm); + var trust : f32 = 1.0; + if (w_norm > 0.0 and r_norm > 0.0) { + trust = @min(w_norm, config.clip_threshold) / r_norm; + } + i = 0; + while (i < n) { + update[i] = -config.learning_rate * trust * update[i]; + i = i + 1; + } + return update[0..n]; + } + + // One LAMB step over several layers packed back to back in `params` (layer k has + // sizes[k] entries), each with its own state; params change in place, each step + 1. + fn forward(params: []f32, grads: []const f32, sizes: []const usize, states: []LAMBState, config: LAMBConfig, scratch: []f32) -> void { + var start : usize = 0; + var k : usize = 0; + while (k < sizes.len) { + const end = start + sizes[k]; + const upd = compute_layer_update(params[start..end], grads[start..end], states[k], config, scratch); + var j : usize = 0; + while (j < sizes[k]) { + params[start + j] = params[start + j] + upd[j]; + j = j + 1; + } + states[k].step = states[k].step + 1; + start = end; + k = k + 1; + } + } + + fn cfg(lr: f32) -> LAMBConfig { + return LAMBConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.01, .clip_threshold = DEFAULT_CLIP_THRESHOLD }; + } + + // which: 0 = m.len, 1 = v.len, 2 = step, 3 = m[0], 4 = v[99] + fn init_probe(which: u8) -> f32 { + var m : [100]f32 = [9.0] ** 100; + var v : [100]f32 = [9.0] ** 100; + const st = init_state(&m, &v, 100); + if (which == 0) { + return @as(f32, @floatFromInt(st.m.len)); + } + if (which == 1) { + return @as(f32, @floatFromInt(st.v.len)); + } + if (which == 2) { + return @as(f32, @floatFromInt(st.step)); + } + if (which == 3) { + return st.m[0]; + } + return st.v[99]; + } + + // update[index] of the first step on params (1, 2, 3), grads (0.1, 0.2, 0.3); index 3 = its length + fn first_update(index: usize) -> f32 { + const params : [3]f32 = [1.0, 2.0, 3.0]; + const grads : [3]f32 = [0.1, 0.2, 0.3]; + var m : [3]f32 = undefined; + var v : [3]f32 = undefined; + var update : [3]f32 = [9.0] ** 3; + const u = compute_layer_update(¶ms, &grads, init_state(&m, &v, 3), cfg(0.001), &update); + if (index == 3) { + return @as(f32, @floatFromInt(u.len)); + } + return u[index]; + } + + // The layer-wise property: scaling a layer's weights by 10 scales its step by 10 + fn step_norm(scale: f32) -> f32 { + const params : [2]f32 = [1.0 * scale, 2.0 * scale]; + const grads : [2]f32 = [0.1, 0.2]; + var m : [2]f32 = undefined; + var v : [2]f32 = undefined; + var update : [2]f32 = undefined; + const u = compute_layer_update(¶ms, &grads, init_state(&m, &v, 2), cfg(0.001), &update); + return sqrt(u[0] * u[0] + u[1] * u[1]); + } + + // Two layers (1, 2) and (3, 4), one step; which: 0..3 = new params, 4 = step of layer 1 + fn two_layers(which: usize) -> f32 { + var params : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + const grads : [4]f32 = [0.1, 0.2, 0.3, 0.4]; + const sizes : [2]usize = [2, 2]; + var m : [4]f32 = undefined; + var v : [4]f32 = undefined; + var states : [2]LAMBState = [init_state(m[0..2], v[0..2], 2), init_state(m[2..4], v[2..4], 2)]; + var scratch : [2]f32 = undefined; + forward(¶ms, &grads, &sizes, &states, cfg(0.001), &scratch); + if (which == 4) { + return @as(f32, @floatFromInt(states[1].step)); + } + return params[which]; + } + + fn valid_input() -> f32 { + return DEFAULT_BETA1; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test init_state_basic_case + given num_params = 100.0 + when m_len = init_probe(0) + then m_len == num_params and init_probe(1) == num_params and init_probe(2) == 0.0 and init_probe(3) == 0.0 and init_probe(4) == 0.0 + + // Every update is negative (descent) and the step's norm is lr * min(||w||, 10) = 0.001 ||w|| + test compute_layer_update_basic_case + given u0 = first_update(0) + when n = first_update(3) + then n == 3.0 and u0 < 0.0 and first_update(1) < 0.0 and first_update(2) < 0.0 and @abs(sqrt(u0 * u0 + first_update(1) * first_update(1) + first_update(2) * first_update(2)) - 0.001 * sqrt(@as(f32, 14.0))) < 0.0000001 + + // Each layer moves, and each layer's state advances + test forward_basic_case + given p0 = two_layers(0) + when p3 = two_layers(3) + then p0 != 1.0 and two_layers(1) != 2.0 and two_layers(2) != 3.0 and p3 != 4.0 and p0 < 1.0 and two_layers(4) == 1.0 + + // LAMB's point: the step is proportional to the layer's weight norm (up to the clip) + test compute_layer_update_scales_with_the_layer + given small = step_norm(1.0) + when large = step_norm(3.0) + then @abs(large / small - 3.0) < 0.001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // 0 < beta1 < 1 + invariant lamb_constraint_0 + assert valid_input() > 0.0 and valid_input() < 1.0 + + // 0 < beta2 < 1 + invariant lamb_constraint_1 + assert DEFAULT_BETA2 > 0.0 and DEFAULT_BETA2 < 1.0 + + // epsilon > 0 + invariant lamb_constraint_2 + assert DEFAULT_EPSILON > 0.0 + + // clip_threshold > 0 + invariant lamb_constraint_3 + assert DEFAULT_CLIP_THRESHOLD > 0.0 + + // name: trust_ratio -- capped by clip_threshold: a layer of norm 50 steps as one of norm 10 + invariant lamb_constraint_4 + assert DEFAULT_CLIP_THRESHOLD == 10.0 + + // name: lamb_update -- bias correction makes the first m_hat equal g + invariant lamb_constraint_5 + assert powi(DEFAULT_BETA1, 1) == DEFAULT_BETA1 and DEFAULT_LR > 0.0 + + // "You et al. (2020) - Large Batch Optimization for Deep Learning: Training BERT in 76 minutes" + invariant lamb_constraint_6 + assert powi(0.5, 3) == 0.125 + + // "Used in BERT, T5, and other large-scale Transformer training" + invariant lamb_constraint_7 + assert DEFAULT_BETA2 > DEFAULT_BETA1 diff --git a/apps/website/public/widgets/nn-lamb/nn-lamb.t27 b/apps/website/public/widgets/nn-lamb/nn-lamb.t27 new file mode 100644 index 0000000000..4d550fb9e8 --- /dev/null +++ b/apps/website/public/widgets/nn-lamb/nn-lamb.t27 @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-lamb.t27 -- LAMB: a layer-wise trust ratio for large batches +; Source of truth for public/widgets/nn-lamb/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-lamb/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/lamb.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 21 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the scale of the weights (1, 2) from 0.1 to 10. Every point is +; step_norm(scale), the norm of the LAMB update for gradients (0.1, 0.2) at lr 0.001, and the tiles +; two_layers, one step on two layers at once. + +; WHAT IT DOES NOT CLAIM: the clip at a norm of 10 is the spec's DEFAULT_CLIP_THRESHOLD; the flat +; part is that cap, not a property of every LAMB. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_lamb; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-lamb"; +pub const TITLE : str = "LAMB: one learning rate for layers of every size"; +pub const DESCRIPTION : str = "Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing."; +pub const IMAGE_ALT : str = "LAMB card at scale 2: a green line rises straight from 0 at scale 0 and bends flat at 0.010 once the scale passes about 4.5, with the cursor at 0.00447. Tiles read step norm 0.004472, ten times the weights 0.010000, and the spec's two layers after one step 0.9984 1.9984 and 2.9965 3.9964."; +pub const HOOK : str = "Weights (2, 4) take a step of 0.00447 and weights (6, 12) one of 0.01: a step is 0.001 of the layer's norm, capped at 10. That is how LAMB trains large batches."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/lamb.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 21 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SCALE_LO_C : u8 = 10; +pub const K_SCALE_HI_C : u16 = 1000; +pub const K_Y_HI_U : u8 = 12; +pub const K_Y_TICKS_U : [5]u8 = [0, 3, 6, 9, 12]; +pub const K_X_TICKS : [6]u8 = [0, 2, 4, 6, 8, 10]; +pub const K_PRESET_SCALE_C : [4]u16 = [200, 600, 10, 1000]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["scale 2", "scale 6, capped", "scale 0.1", "scale 10"]; +pub const SAY_ASK : str = "Can one learning rate suit a tiny layer and a huge one?"; +pub const SAY_SCALE : str = "weight scale"; +pub const SAY_NORM : str = "step norm"; +pub const SAY_PLOT_LABEL : str = "The norm of one LAMB step as the layer's weights are scaled"; +pub const SAY_NORM_X10 : str = "weights x 10"; +pub const SAY_LAYER_A : str = "layer 1 after a step"; +pub const SAY_LAYER_B : str = "layer 2 after a step"; +pub const SAY_NOTE : str = "LAMB computes an Adam-style update for each layer, then rescales it by the trust ratio min(||w||, 10) / ||update||. A big layer takes a big step and a small layer a small one."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/lamb.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_window_reaches_the_cap { + assert K_SCALE_HI_C == 1000; + assert K_PRESET_SCALE_C[1] > 448; + assert K_PRESET_SCALE_C[0] < 448; +} + +test the_axis_holds_the_cap { + assert K_Y_HI_U > 10; + assert K_Y_TICKS_U[4] == K_Y_HI_U; + assert K_PRESET_SCALE_C[2] == K_SCALE_LO_C; +} diff --git a/apps/website/public/widgets/nn-lamb/tool.js b/apps/website/public/widgets/nn-lamb/tool.js new file mode 100644 index 0000000000..da6ce788b0 --- /dev/null +++ b/apps/website/public/widgets/nn-lamb/tool.js @@ -0,0 +1,34 @@ +// nn-lamb/tool.js -- lesson 21 of neural-networks: one learning rate for layers of every size. LAMB +// scales each layer's Adam-style update by a trust ratio, the layer's weight norm over its update +// norm (the weight norm capped at 10), so the step is a fixed fraction of the layer. Every point is +// step_norm and every tile two_layers of gHashTag/t27 specs/ml/optimizer/lamb.t27, compiled to wasm +// (./logic.js): weights (1, 2) times a scale, gradients (0.1, 0.2), lr 0.001. Words are SAY_ and +// numbers K_ constants of specs/widgets/nn-lamb.t27. +import { stepNorm, twoLayers } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const S0 = centi(K('K_SCALE_LO_C', 10)), S1 = centi(K('K_SCALE_HI_C', 1000)) +const ctl = controls([ + { key: 'k', label: say('SAY_SCALE'), min: S0, max: S1, step: 0.05, fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { k: K('K_PRESET_SCALE_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_NORM'), COLORS[0]]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 330, x0: S0, x1: S1, y0: 0, y1: K('K_Y_HI_U', 12) / 1000, xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS_U', []).map((t) => t / 1000), yfmt: (t) => fmt(t, 3), xlabel: say('SAY_SCALE'), left: 60 } + const p = plot(svg, o) + p.line(sample((k) => stepNorm(k), S0, S1, 240), COLORS[0], 3.5) + cursor(svg, p, s.k, [[stepNorm(s.k), COLORS[1]]]) + dragX(svg, p, o, (k) => ctl.set('k', k)) + stat.replaceChildren(tiles([ + { label: say('SAY_NORM'), value: fmt(stepNorm(s.k), 6), tone: 0 }, + { label: say('SAY_NORM_X10'), value: fmt(stepNorm(s.k * 10), 6), tone: 1 }, + { label: say('SAY_LAYER_A'), value: [0, 1].map((i) => fmt(twoLayers(i), 4)).join(' '), tone: 2 }, + { label: say('SAY_LAYER_B'), value: [2, 3].map((i) => fmt(twoLayers(i), 4)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-lstm/card.png b/apps/website/public/widgets/nn-lstm/card.png new file mode 100644 index 0000000000000000000000000000000000000000..160151aa47a30ce3bbf118c0d2944d1c6aef773d GIT binary patch literal 65435 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�QZhSo~&Vz%kELh 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 Z2P5uyO89QIE9&2XWu=rPtHq52{~tv4Y6JiP literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-lstm/index.html b/apps/website/public/widgets/nn-lstm/index.html new file mode 100644 index 0000000000..172d0cee1b --- /dev/null +++ b/apps/website/public/widgets/nn-lstm/index.html @@ -0,0 +1,47 @@ + + + + + + +LSTM gates: how a cell decides what to keep · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

LSTM gates: how a cell decides what to keep

+

Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/recurrent/lstm_single.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 23 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-lstm/logic.js b/apps/website/public/widgets/nn-lstm/logic.js new file mode 100644 index 0000000000..92a14e93f3 --- /dev/null +++ b/apps/website/public/widgets/nn-lstm/logic.js @@ -0,0 +1,48 @@ +// Generated by scripts/t27-logic.mjs from lstm_single.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: ef4ffa30e7adf81c8467768ec637ba33643c7872f6746cf244cdaa12eff68385 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-lstm/: types stripped, nothing else changed. +const WASM = "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IAEgAUEIakEwajYC4AMgAUECNgLcAyABIAFBCGpBKGo2AtgDIAFBBDYC1AMgASABQQhqQRhqNgLQAyABQQY2AswDIAEgAUHQAWo2AsADIAEgAUHIAWo2ArgDIAEgAUEIajYCyAMgAUKDgICAIDcDqAQgAUECNgK0BCABQQI2ArwEIAFBBjYCxAQgASABQfgBakEYajYCyAQgAUEENgLMBCABIAFB+AFqQShqNgLQBCABQQI2AtQEIAEgAUH4AWpBMGo2AtgEIAFBBjYC3AQgASABQfgBakHIAGo2AuAEIAFBBDYC5AQgASABQfgBakHYAGo2AugEIAFBAjYC7AQgASABQfgBakHgAGo2AvAEIAFBBjYC9AQgASABQfgBakH4AGo2AvgEIAFBBDYC/AQgASABQfgBakGIAWo2AoAFIAFBAjYChAUgASABQfgBakGQAWo2AogFIAFBBjYCjAUgASABQfgBakGoAWo2ApAFIAFBBDYClAUgASABQfgBakG4AWo2ApgFIAFBAjYCnAUgASABQegBajYCsAQgASABQfABajYCuAQgASABQfgBajYCwARBlIDAgABBnIDAgAAgAUG4A2ogAUHIA2ogAUGoBGogAUHYAWogAUGwBGogAUHABGoQioCAgAACQAJAIABBf2pBAksNACABQdgBaiAAQQJ0akF8aioCACECDAELAkACQAJAIABBfnFBfGoOAwACAQILIAFB6AFqIABBAnRqQXBqKgIAIQIMAgsgAUHwAWogAEECdGpBaGoqAgAhAgwBCyABKgLUAiECCyABQaAFaiSAgICAACACCwwAIAAgARCHgICAAAsXAEMAAIA/IACMEI+AgIAAQwAAgD+SlQvUAgIDfwN9AkACQCAAIABcDQAgALwiAUEfdiECAkACQAJAAkACQAJAAkAgAUH/////B3EiA0HP2LqVBEsNACADQZjkxfUDTQ0BIANBkquU/ANNDQIMBAsgA0GAgID8B0sNBgJAIAFBAEgNACADQZjkxZUESQ0AIABDAAAAf5QPCyABQX9KDQNDAAAAACEEIANBtOO/lgRLDQcMAwsgA0GAgIDIA00NAUEAIQNDAAAAACEFIAAhBAwECyACQQFzIAJrIQMMAgsgAEMAAIA/kg8LIABDO6q4P5QgAkECdCoCpIDAgACS/AAhAwsgACADsiIEQwByMb+UkiIAIARDjr6/NZQiBZMhBAsgACAEIAQgBCAElCIGIAZDFVI1u5RDj6oqPpKUkyIGlEMAAABAIAaTlSAFk5JDAACAP5IhBCADRQ0BIAQgAxCQgICAAA8LIAAhBAsgBAumAgEEfwJAAkAgACAAXA0AIAC8IgJB/////wdxQYCAgPwHTw0AIAJBgICAgHhxIQNBCCACQQF0IgRnayAEQRh2IARBgICACEkbIQQCQCABQQBIDQACQCABQf4BIARrTA0AQwAAgH8gAJgPCwJAIAQgAWoiBUEASg0AIAIgAXQgA3K+DwsCQCAEQQBKDQAgAkEBIARrdEH///8DcSAFQRd0ciADcr4PCyABQRd0IAJqvg8LIAFBACAEa0oNAQJAIAFBaSAEa04NACADvg8LQYCAgARBACAEQQBKGyACQf///wNxckEAIAFrIgNBASABIARqayIBIAMgAUgbQX9qIgF2QQFqQQF2IAJoIAFBH3FGQX9zcb4gAJghAAsgAA8LIAFBF3QgAmq+Cws1AQBBgIDAAAssAACAPwAAAEAAAEBAAAAAAAAAAAAAAAA/mpmZvs3MTD7NzMw9AAAAPwAAAL8="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function sigmoid(z) { + return W.t27_sigmoid(z); +} +function loss(which, delta) { + return W.t27_loss(int(which, 0, 4294967295, "loss.which"), delta); +} +function grad(which) { + return W.t27_grad(int(which, 0, 4294967295, "grad.which")); +} +function zeroUpstreamTotal() { + return W.t27_zero_upstream_total(); +} +function slope(which) { + return W.t27_slope(int(which, 0, 4294967295, "slope.which")); +} +function biasOnly(bI, bF, bG, bO, cPrev, which) { + return W.t27_bias_only(bI, bF, bG, bO, cPrev, int(which, 0, 255, "bias_only.which")); +} +function validInput() { + return W.t27_valid_input() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["pre", "forward", "spread", "backward", "cfg", "weights_of", "fill"]); +export { + __NOT_LOWERED__, + biasOnly, + grad, + loss, + sigmoid, + slope, + validInput, + zeroUpstreamTotal +}; diff --git a/apps/website/public/widgets/nn-lstm/logic.t27 b/apps/website/public/widgets/nn-lstm/logic.t27 new file mode 100644 index 0000000000..bc16437835 --- /dev/null +++ b/apps/website/public/widgets/nn-lstm/logic.t27 @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// LSTM solves vanishing gradient problem | φ² + 1/φ² = 3 | TRINITY + +// #8980: called `@sigmoid` and `@tanh`, which Zig does not have; each gate weight +// was one number per INPUT, indexed `i % hidden_size`, so it was not an LSTM; and +// every test asserted `true`. Now each gate has its own matrices, W_x +// (hidden x input) and W_h (hidden x hidden), and a bias: +// i = s(z_i), f = s(z_f), g = tanh(z_g), o = s(z_o), z = W_x x + W_h h + b +// c' = f c + i g, h' = o tanh(c') +// backward gives every gradient of one step, and the tests check it against finite +// differences. + +module LstmCell; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const FORGET_BIAS_INIT : f32 = 1.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const LSTMConfig = struct { + input_size : u32, + hidden_size : u32, + }; + + pub const LSTMState = struct { + h : []f32, + c : []f32, + }; + + pub const LSTMWeights = struct { + W_ii : []f32, + W_hi : []f32, + b_i : []f32, + W_if : []f32, + W_hf : []f32, + b_f : []f32, + W_ig : []f32, + W_hg : []f32, + b_g : []f32, + W_io : []f32, + W_ho : []f32, + b_o : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + fn sigmoid(z: f32) -> f32 { + return 1.0 / (1.0 + exp(-z)); + } + + // Pre-activation of one gate for hidden unit u: W_x[u] . x + W_h[u] . h + b[u] + fn pre(w_x: []const f32, w_h: []const f32, b: []const f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig) -> f32 { + var z : f32 = b[u]; + var j : usize = 0; + while (j < config.input_size) { + z = z + w_x[u * config.input_size + j] * x[j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + z = z + w_h[u * config.hidden_size + k] * h[k]; + k = k + 1; + } + return z; + } + + fn forward(input: []const f32, state: LSTMState, weights: LSTMWeights, output_state: LSTMState, config: LSTMConfig) -> void { + var u : usize = 0; + while (u < config.hidden_size) { + const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config)); + const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config)); + const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config)); + const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config)); + output_state.c[u] = fg * state.c[u] + ig * gg; + output_state.h[u] = og * tanh(output_state.c[u]); + u = u + 1; + } + } + + // Adds dz * (x, h, 1) into one gate's weight gradients, and dz * W into grad_input / grad_state.h + fn spread(dz: f32, w_x: []const f32, w_h: []const f32, gw_x: []f32, gw_h: []f32, gb: []f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig, grad_input: []f32, grad_h: []f32) -> void { + var j : usize = 0; + while (j < config.input_size) { + gw_x[u * config.input_size + j] = gw_x[u * config.input_size + j] + dz * x[j]; + grad_input[j] = grad_input[j] + dz * w_x[u * config.input_size + j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + gw_h[u * config.hidden_size + k] = gw_h[u * config.hidden_size + k] + dz * h[k]; + grad_h[k] = grad_h[k] + dz * w_h[u * config.hidden_size + k]; + k = k + 1; + } + gb[u] = gb[u] + dz; + } + + // One step back. grad_output = dL/dh', grad_cell = dL/dc' from later steps. Writes + // dL/dx, dL/dh, dL/dc and ADDS the weight gradients into grad_weights. + // do = dh' tanh(c'); dc = dh' o (1 - tanh^2 c') + grad_cell + // dz_o = do o (1 - o), dz_f = dc c f (1 - f), dz_i = dc g i (1 - i), dz_g = dc i (1 - g^2) + // dL/dc = dc f + fn backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, config: LSTMConfig, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void { + var j : usize = 0; + while (j < config.input_size) { + grad_input[j] = 0.0; + j = j + 1; + } + var u : usize = 0; + while (u < config.hidden_size) { + grad_state.h[u] = 0.0; + u = u + 1; + } + u = 0; + while (u < config.hidden_size) { + const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config)); + const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config)); + const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config)); + const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config)); + const c_new = fg * state.c[u] + ig * gg; + const tc = tanh(c_new); + const dc = grad_output[u] * og * (1.0 - tc * tc) + grad_cell[u]; + const dz_o = grad_output[u] * tc * og * (1.0 - og); + const dz_f = dc * state.c[u] * fg * (1.0 - fg); + const dz_i = dc * gg * ig * (1.0 - ig); + const dz_g = dc * ig * (1.0 - gg * gg); + grad_state.c[u] = dc * fg; + spread(dz_i, weights.W_ii, weights.W_hi, grad_weights.W_ii, grad_weights.W_hi, grad_weights.b_i, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_f, weights.W_if, weights.W_hf, grad_weights.W_if, grad_weights.W_hf, grad_weights.b_f, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_g, weights.W_ig, weights.W_hg, grad_weights.W_ig, grad_weights.W_hg, grad_weights.b_g, input, state.h, u, config, grad_input, grad_state.h); + spread(dz_o, weights.W_io, weights.W_ho, grad_weights.W_io, grad_weights.W_ho, grad_weights.b_o, input, state.h, u, config, grad_input, grad_state.h); + u = u + 1; + } + } + + // The fixture: input 3, hidden 2. All 48 weights live in one buffer, per gate + // W_x (6), W_h (4), b (2), in the gate order i, f, g, o. + fn cfg() -> LSTMConfig { + return LSTMConfig{ .input_size = 3, .hidden_size = 2 }; + } + + fn weights_of(w: []f32) -> LSTMWeights { + return LSTMWeights{ + .W_ii = w[0..6], .W_hi = w[6..10], .b_i = w[10..12], + .W_if = w[12..18], .W_hf = w[18..22], .b_f = w[22..24], + .W_ig = w[24..30], .W_hg = w[30..34], .b_g = w[34..36], + .W_io = w[36..42], .W_ho = w[42..46], .b_o = w[46..48], + }; + } + + // Deterministic weights in [-0.5, 0.5]; the forget biases start at FORGET_BIAS_INIT + fn fill(w: []f32) -> void { + var k : usize = 0; + while (k < 48) { + w[k] = @as(f32, @floatFromInt((k * 7 + 3) % 11)) / 10.0 - 0.5; + k = k + 1; + } + w[22] = FORGET_BIAS_INIT; + w[23] = FORGET_BIAS_INIT; + } + + // L = 0.5 h'_0 - 0.3 h'_1 + 0.2 c'_0 + 0.1 c'_1 after one step, with one input, one h or + // one c entry moved by `delta` (which: 0 = none, 1 + j = x_j, 4 + k = h_k, 6 + k = c_k, + // 8 = b_f[1]) + fn loss(which: usize, delta: f32) -> f32 { + var w : [48]f32 = undefined; + fill(&w); + var x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + if (which >= 1 and which <= 3) { + x[which - 1] = x[which - 1] + delta; + } + if (which >= 4 and which <= 5) { + h[which - 4] = h[which - 4] + delta; + } + if (which >= 6 and which <= 7) { + c[which - 6] = c[which - 6] + delta; + } + if (which == 8) { + w[23] = w[23] + delta; + } + var h_out : [2]f32 = [0.0] ** 2; + var c_out : [2]f32 = [0.0] ** 2; + forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg()); + return 0.5 * h_out[0] - 0.3 * h_out[1] + 0.2 * c_out[0] + 0.1 * c_out[1]; + } + + // The analytic gradient of that loss, same `which` numbering + fn grad(which: usize) -> f32 { + var w : [48]f32 = undefined; + fill(&w); + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + const grad_output : [2]f32 = [0.5, -0.3]; + const grad_cell : [2]f32 = [0.2, 0.1]; + var gx : [3]f32 = [0.0] ** 3; + var gh : [2]f32 = [0.0] ** 2; + var gc : [2]f32 = [0.0] ** 2; + var gw : [48]f32 = [0.0] ** 48; + backward(&grad_output, &grad_cell, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw)); + if (which >= 1 and which <= 3) { + return gx[which - 1]; + } + if (which >= 4 and which <= 5) { + return gh[which - 4]; + } + if (which >= 6 and which <= 7) { + return gc[which - 6]; + } + return gw[23]; + } + + // Sum of |every gradient| when grad_output and grad_cell are both 0 + fn zero_upstream_total() -> f32 { + var w : [48]f32 = undefined; + fill(&w); + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.1, 0.2]; + var c : [2]f32 = [0.3, 0.4]; + const zeros : [2]f32 = [0.0, 0.0]; + var gx : [3]f32 = [0.0] ** 3; + var gh : [2]f32 = [0.0] ** 2; + var gc : [2]f32 = [0.0] ** 2; + var gw : [48]f32 = [0.0] ** 48; + backward(&zeros, &zeros, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw)); + var total : f32 = @abs(gx[0]) + @abs(gx[1]) + @abs(gx[2]) + @abs(gh[0]) + @abs(gh[1]) + @abs(gc[0]) + @abs(gc[1]); + var k : usize = 0; + while (k < 48) { + total = total + @abs(gw[k]); + k = k + 1; + } + return total; + } + + fn slope(which: usize) -> f32 { + return (loss(which, 0.001) - loss(which, -0.001)) / 0.002; + } + + // which: 0 = h'_0, 1 = c'_0 for a 1-unit cell with every weight 0 and the given biases + fn bias_only(b_i: f32, b_f: f32, b_g: f32, b_o: f32, c_prev: f32, which: u8) -> f32 { + var w : [48]f32 = [0.0] ** 48; + w[10] = b_i; + w[22] = b_f; + w[34] = b_g; + w[46] = b_o; + const x : [3]f32 = [1.0, 2.0, 3.0]; + var h : [2]f32 = [0.0, 0.0]; + var c : [2]f32 = [c_prev, 0.0]; + var h_out : [2]f32 = [9.0] ** 2; + var c_out : [2]f32 = [9.0] ** 2; + forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg()); + if (which == 0) { + return h_out[0]; + } + return c_out[0]; + } + + fn valid_input() -> usize { + return cfg().input_size; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // All weights 0: every gate is s(0) = 0.5 or tanh(0) = 0, so c' = 0.5 c and h' = 0.5 tanh(c') + test forward_basic_case + given c_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 1) + when h_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 0) + then @abs(c_new - 0.4) < 0.000001 and @abs(h_new - 0.5 * tanh(c_new)) < 0.000001 and @abs(h_new - 0.1899745) < 0.000001 + + // A closed forget gate (b_f = -30) erases the old cell; an open one (b_f = 30) keeps it + test forward_basic_lstm + given erased = bias_only(0.0, -30.0, 0.0, 0.0, 0.8, 1) + when kept = bias_only(-30.0, 30.0, 0.0, 0.0, 0.8, 1) + then @abs(erased) < 0.000001 and @abs(kept - 0.8) < 0.000001 + + // A closed input gate and forget gate leave c' = 0, so h' = 0 whatever the output gate does + test forward_with_empty_input + given h_new = bias_only(-30.0, -30.0, 1.0, 30.0, 0.8, 0) + then @abs(h_new) < 0.000001 + + // dL/dx_j against central differences + test backward_basic_case + given g0 = grad(1) + when g2 = grad(3) + then @abs(g0 - slope(1)) < 0.0005 and @abs(grad(2) - slope(2)) < 0.0005 and @abs(g2 - slope(3)) < 0.0005 + + // dL/dh_k, dL/dc_k and dL/db_f[1] against central differences + test backward_basic_lstm + given gh0 = grad(4) + when gc1 = grad(7) + then @abs(gh0 - slope(4)) < 0.0005 and @abs(grad(5) - slope(5)) < 0.0005 and @abs(grad(6) - slope(6)) < 0.0005 and @abs(gc1 - slope(7)) < 0.0005 and @abs(grad(8) - slope(8)) < 0.0005 + + // With no upstream gradient nothing flows back + test backward_with_empty_grad + given total = zero_upstream_total() + then total == 0.0 and @abs(grad(1)) > 0.0 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // input.size() == config.input_size + invariant lstm_cell_constraint_0 + assert valid_input() == 3 + + // state.h.size() == config.hidden_size + invariant lstm_cell_constraint_1 + assert cfg().hidden_size == 2 + + // state.c.size() == config.hidden_size; the forget bias starts open + invariant lstm_cell_constraint_2 + assert FORGET_BIAS_INIT > 0.0 diff --git a/apps/website/public/widgets/nn-lstm/nn-lstm.t27 b/apps/website/public/widgets/nn-lstm/nn-lstm.t27 new file mode 100644 index 0000000000..aeaa04a2ba --- /dev/null +++ b/apps/website/public/widgets/nn-lstm/nn-lstm.t27 @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-lstm.t27 -- an LSTM cell's gates: forget, input, output +; Source of truth for public/widgets/nn-lstm/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-lstm/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/lstm_single.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 23 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets four gate biases from -6 to 6 and the old memory from -2 to 2. With +; every weight 0, each gate is sigmoid(bias); the new memory and output are bias_only(b_i, b_f, b_g, +; b_o, c_prev, which) of the spec. + +; WHAT IT DOES NOT CLAIM: one step of a 1-unit cell with all weights 0, so the gates see only their +; biases; that is the spec's own fixture. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_lstm; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-lstm"; +pub const TITLE : str = "LSTM gates: how a cell decides what to keep"; +pub const DESCRIPTION : str = "Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate."; +pub const IMAGE_ALT : str = "LSTM card, remember: gate bars forget 0.998, input 0.002 and output 0.998; memory bars old 1.000, new 0.998 and output 0.759. Tiles read new memory 0.9975, output 0.7587, forget 0.9975 and input 0.0025."; +pub const HOOK : str = "With the forget gate open (0.9975) and the input gate shut, a memory of 1 comes out as 0.9975: an LSTM can hold a value for a long time."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/lstm_single.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 23 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_BIAS_HI_C : u16 = 600; +pub const K_C_LO_C : i16 = -200; +pub const K_C_HI_C : u16 = 200; +pub const K_CELL_LO : i8 = -3; +pub const K_CELL_HI : u8 = 3; +pub const K_GATE_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_CELL_TICKS : [5]i8 = [-2, -1, 0, 1, 2]; +pub const K_PRESET_BF_C : [4]i16 = [600, -600, -600, 600]; +pub const K_PRESET_BI_C : [4]i16 = [-600, 0, 600, -600]; +pub const K_PRESET_BG_C : [4]i16 = [0, 0, 600, 0]; +pub const K_PRESET_BO_C : [4]i16 = [600, 600, 600, -600]; +pub const K_PRESET_C_C : [4]i16 = [100, 100, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Remember", "Forget", "Write", "Hide"]; +pub const SAY_ASK : str = "How does a memory cell decide what to keep and what to forget?"; +pub const SAY_BF : str = "forget bias"; +pub const SAY_BI : str = "input bias"; +pub const SAY_BG : str = "candidate bias"; +pub const SAY_BO : str = "output bias"; +pub const SAY_C_PREV : str = "old memory c"; +pub const SAY_GATES_LABEL : str = "The three gates, each a sigmoid of its bias"; +pub const SAY_CELL_LABEL : str = "The memory before and after, and the output"; +pub const SAY_FORGET : str = "forget"; +pub const SAY_INPUT : str = "input"; +pub const SAY_OUTPUT : str = "output"; +pub const SAY_C_OLD : str = "old c"; +pub const SAY_C_NEW : str = "new c"; +pub const SAY_H_NEW : str = "output h"; +pub const SAY_NOTE : str = "c' = f c + i g and h' = o tanh(c'). When f is near 1 and i near 0, c passes through almost untouched, and so does its gradient: the long memory the plain cell lacked."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/lstm_single.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_biases_are_symmetric { + assert K_BIAS_HI_C == 600; + assert K_PRESET_BF_C[1] + K_BIAS_HI_C == 0; + assert K_PRESET_BG_C[2] == K_BIAS_HI_C; +} + +test the_presets_cover_the_gates { + assert K_PRESET_BF_C[0] > 0; + assert K_PRESET_BI_C[0] < 0; + assert K_PRESET_BO_C[3] < 0; + assert K_PRESET_C_C[0] <= K_C_HI_C; +} diff --git a/apps/website/public/widgets/nn-lstm/tool.js b/apps/website/public/widgets/nn-lstm/tool.js new file mode 100644 index 0000000000..396a38c432 --- /dev/null +++ b/apps/website/public/widgets/nn-lstm/tool.js @@ -0,0 +1,35 @@ +// nn-lstm/tool.js -- lesson 23 of neural-networks: how a cell decides what to keep. An LSTM has three +// gates, each a sigmoid: forget scales the old memory, input lets new content in, output decides +// how much of the memory to show. Here every weight is 0, so each gate is the sigmoid of its bias. +// The gates are sigmoid and the new memory and output are bias_only of gHashTag/t27 +// specs/ml/recurrent/lstm_single.t27, compiled to wasm (./logic.js). Words are SAY_ and numbers K_ +// constants of specs/widgets/nn-lstm.t27. +import { biasOnly, sigmoid } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, el, fmt, root, say, source, tiles } from '../nn-kit.js' + +const B = centi(K('K_BIAS_HI_C', 600)) +const bias = (key, label) => ({ key, label, min: -B, max: B, step: 0.5, fmt: (v) => fmt(v, 1) }) +const ctl = controls([ + bias('bf', say('SAY_BF')), bias('bi', say('SAY_BI')), bias('bg', say('SAY_BG')), bias('bo', say('SAY_BO')), + { key: 'c', label: say('SAY_C_PREV'), min: centi(K('K_C_LO_C', -200)), max: centi(K('K_C_HI_C', 200)), step: 0.1, fmt: (v) => fmt(v, 1) }, +], { names: W.SAY_PRESET_NAMES, values: { bf: K('K_PRESET_BF_C', []).map(centi), bi: K('K_PRESET_BI_C', []).map(centi), bg: K('K_PRESET_BG_C', []).map(centi), bo: K('K_PRESET_BO_C', []).map(centi), c: K('K_PRESET_C_C', []).map(centi) } }, draw) + +const gates = canvas('nn-bars', say('SAY_GATES_LABEL')) +const cell = canvas('nn-bars', say('SAY_CELL_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('div', { class: 'nn-two' }, el('div', {}, el('p', { class: 'dk-label' }, say('SAY_GATES_LABEL')), gates), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_CELL_LABEL')), cell)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const g = [sigmoid(s.bf), sigmoid(s.bi), sigmoid(s.bo)] + bars(gates, { values: g, labels: [say('SAY_FORGET'), say('SAY_INPUT'), say('SAY_OUTPUT')], colors: [COLORS[4], COLORS[2], COLORS[5]], lo: 0, hi: 1, h: 240, ticks: K('K_GATE_TICKS_C', []).map(centi), fmt: (v) => fmt(v, 3) }) + const c2 = biasOnly(s.bi, s.bf, s.bg, s.bo, s.c, 1), h2 = biasOnly(s.bi, s.bf, s.bg, s.bo, s.c, 0) + bars(cell, { values: [s.c, c2, h2], labels: [say('SAY_C_OLD'), say('SAY_C_NEW'), say('SAY_H_NEW')], colors: [COLORS[6], COLORS[0], COLORS[1]], lo: K('K_CELL_LO', -3), hi: K('K_CELL_HI', 3), h: 240, ticks: K('K_CELL_TICKS', []), fmt: (v) => fmt(v, 3) }) + stat.replaceChildren(tiles([ + { label: say('SAY_C_NEW'), value: fmt(c2, 4), tone: 0 }, + { label: say('SAY_H_NEW'), value: fmt(h2, 4), tone: 1 }, + { label: say('SAY_FORGET'), value: fmt(g[0], 4), tone: 4 }, + { label: say('SAY_INPUT'), value: fmt(g[1], 4), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-maxpool/card.png b/apps/website/public/widgets/nn-maxpool/card.png new file mode 100644 index 0000000000000000000000000000000000000000..055a66da37ede022f2842c05da9f604a59c7c51d GIT binary patch literal 43202 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�BA>hoXH2{0J| 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-maxpool/index.html b/apps/website/public/widgets/nn-maxpool/index.html new file mode 100644 index 0000000000..2048f4cdda --- /dev/null +++ b/apps/website/public/widgets/nn-maxpool/index.html @@ -0,0 +1,47 @@ + + + + + + +Max pooling: what a network keeps when it shrinks a picture · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Max pooling: what a network keeps when it shrinks a picture

+

Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-maxpool/logic.js b/apps/website/public/widgets/nn-maxpool/logic.js new file mode 100644 index 0000000000..62c5f07970 --- /dev/null +++ b/apps/website/public/widgets/nn-maxpool/logic.js @@ -0,0 +1,28 @@ +// Generated by scripts/t27-logic.mjs from maxpool2d_layer.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 70e420bb07469fa920c9fabeaaa29116ee913b5b203951594cfb7ef20730db46 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-maxpool/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABFANgAX8BfWADf39/AGAEf39/fwF9AwQDAAECBAUBcAEBAQUDAQARBgkBfwFBgIDAAAsHKgMGbWVtb3J5AgAPdDI3X2JhY2t3YXJkX2F0AAALdDI3X3Bvb2xfYXQAAgqOBgONAgIDfwF9I4CAgIAAQYABayIBJICAgIAAIAFBIGpCADcDACABQgA3AxggAUKAgICAEDcCNCABQoKAgIAgNwIsIAFBAToAPCABQQE6AEAgAUEsaiABQQhqIAFBGGoQgYCAgAACQEHAAEUNACABQcAAakHAgMCAAEHAAPwKAAALQQAhAgN9AkAgAkHAAEcNAEEAIQICQANAIAJBEEYNASABQcAAaiABQRhqIAJqKAIAQQJ0aiIDIAMqAgAgAkGAgcCAAGoqAgCSOAIAIAJBBGohAgwACwsgAUHAAGogAEECdGoqAgAhBCABQYABaiSAgICAACAEDwsgAUHAAGogAmpBADYCACACQQRqIQIMAAsLygIBFH8gACgCBCIDQQR0IQQgA0ECdCEFQQQgACgCACIGayADbiIHQQFqIQhBACEJQYCAwIAAIQpBACELAkADQCALIAdLDQEgCyAIbCEMIAsgBWwhDUEAIQ4gCiEPIAkhEANAAkACQCAOIAdLDQAgDiADbCANaiERQQAhEiAPIRMgECEUA0AgEiAGRg0CIBMhFSAUIRYgBiEAAkADQCAARQ0BIBYgESAVKgIAIBFBAnRBgIDAgABqKgIAXhshESAVQQRqIRUgFkEBaiEWIABBf2ohAAwACwsgE0EQaiETIBRBBGohFCASQQFqIRIMAAsLIAogBGohCiAJIAVqIQkgC0EBaiELDAILIAEgDiAMakECdCIAaiARQQJ0QYCAwIAAaioCADgCACACIABqIBE2AgAgDyAFaiEPIBAgA2ohECAOQQFqIQ4MAAsLCwuwAQICfwF9I4CAgIAAQeAAayIEJICAgIAAAkBBJEUiBQ0AIARBAEEk/AsACwJAIAUNACAEQSRqQQBBJPwLAAsgBEKAgICAEDcCUCAEIAE2AkwgBCAANgJIIARBAToAWCAEQQE6AFwgBEHIAGogBCAEQSRqEIGAgIAAAkACQCACDQAgBCADQQJ0aioCACEGDAELIARBJGogA0ECdGooAgCzIQYLIARB4ABqJICAgIAAIAYLC5oBAQBBgIDAAAuQAQAAgD8AAABAAACgQAAAwEAAAEBAAACAQAAAAEEAAOBAAAAAAAAAgL8AAEDAAAAAwAAAgMAAABBBAADAwAAAoMAAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAACAPwAAAEAAAEBAAACAQA=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function poolAt(kernel, stride, which, index) { + return W.t27_pool_at(int(kernel, 0, 4294967295, "pool_at.kernel"), int(stride, 0, 4294967295, "pool_at.stride"), int(which, 0, 255, "pool_at.which"), int(index, 0, 4294967295, "pool_at.index")); +} +function backwardAt(index) { + return W.t27_backward_at(int(index, 0, 4294967295, "backward_at.index")); +} +const __NOT_LOWERED__ = Object.freeze(["out_size", "forward", "backward", "cfg"]); +export { + __NOT_LOWERED__, + backwardAt, + poolAt +}; diff --git a/apps/website/public/widgets/nn-maxpool/logic.t27 b/apps/website/public/widgets/nn-maxpool/logic.t27 new file mode 100644 index 0000000000..6841238ca8 --- /dev/null +++ b/apps/website/public/widgets/nn-maxpool/logic.t27 @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Reduce spatial dimensions | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward and backward compared two values and threw them away +// (placeholders), and every test asserted `result != undefined`. Max pooling now +// runs over one H x W channel (row-major) with a k x k window and a stride. It +// records each window's argmax, and backward sends each gradient back to that +// element only. Padding and dilation are carried in the config but not read: the +// layer assumes padding 0 and dilation 1. + +module Maxpool2d; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const MaxPool2DConfig = struct { + kernel_size : u32, + stride : u32, + padding : u32, + dilation : u32, + return_indices : bool, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // Output side for an input side n: (n - k) / stride + 1 + fn out_size(n: u32, config: MaxPool2DConfig) -> u32 { + return (n - config.kernel_size) / config.stride + 1; + } + + // output[oy][ox] = max of the k x k window at (oy * stride, ox * stride); + // indices[oy][ox] = the flat input index that held it + fn forward(input: []const f32, height: u32, width: u32, config: MaxPool2DConfig, output: []f32, indices: []u32) -> void { + const oh = out_size(height, config); + const ow = out_size(width, config); + var oy : u32 = 0; + while (oy < oh) { + var ox : u32 = 0; + while (ox < ow) { + var best_index : u32 = (oy * config.stride) * width + ox * config.stride; + var ky : u32 = 0; + while (ky < config.kernel_size) { + var kx : u32 = 0; + while (kx < config.kernel_size) { + const idx : u32 = (oy * config.stride + ky) * width + ox * config.stride + kx; + if (input[idx] > input[best_index]) { + best_index = idx; + } + kx = kx + 1; + } + ky = ky + 1; + } + output[oy * ow + ox] = input[best_index]; + indices[oy * ow + ox] = best_index; + ox = ox + 1; + } + oy = oy + 1; + } + } + + // grad_input[indices[o]] += grad_output[o]; every other input gets 0 + fn backward(grad_output: []const f32, indices: []const u32, grad_input: []f32) -> void { + var i : usize = 0; + while (i < grad_input.len) { + grad_input[i] = 0.0; + i = i + 1; + } + var o : usize = 0; + while (o < grad_output.len) { + grad_input[indices[o]] = grad_input[indices[o]] + grad_output[o]; + o = o + 1; + } + } + + fn cfg(kernel: u32, stride: u32) -> MaxPool2DConfig { + return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; + } + + // The 4 x 4 fixture + // 1 2 5 6 + // 3 4 8 7 + // 0 -1 -3 -2 + // -4 9 -6 -5 + fn pool_at(kernel: u32, stride: u32, which: u8, index: usize) -> f32 { + const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0]; + var output : [9]f32 = [0.0] ** 9; + var indices : [9]u32 = [0] ** 9; + forward(&input, 4, 4, cfg(kernel, stride), &output, &indices); + if (which == 0) { + return output[index]; + } + return @as(f32, @floatFromInt(indices[index])); + } + + // 2 x 2, stride 2, gradients (1, 2, 3, 4) for the four windows; grad_input[index] + fn backward_at(index: usize) -> f32 { + const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0]; + var output : [4]f32 = [0.0] ** 4; + var indices : [4]u32 = [0] ** 4; + forward(&input, 4, 4, cfg(2, 2), &output, &indices); + const grad_output : [4]f32 = [1.0, 2.0, 3.0, 4.0]; + var grad_input : [16]f32 = [9.0] ** 16; + backward(&grad_output, &indices, &grad_input); + return grad_input[index]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // 2 x 2, stride 2: windows' maxima are 4, 8, 9, -2 + test forward_basic_case + given first = pool_at(2, 2, 0, 0) + when last = pool_at(2, 2, 0, 3) + then first == 4.0 and pool_at(2, 2, 0, 1) == 8.0 and pool_at(2, 2, 0, 2) == 9.0 and last == -2.0 + + // The argmax indices: 4 at 5, 8 at 6, 9 at 13, -2 at 11 + test forward_max_finding + given first = pool_at(2, 2, 1, 0) + when third = pool_at(2, 2, 1, 2) + then first == 5.0 and pool_at(2, 2, 1, 1) == 6.0 and third == 13.0 and pool_at(2, 2, 1, 3) == 11.0 + + // 3 x 3, stride 1 gives a 2 x 2 output whose windows overlap + test forward_overlapping_windows + given first = pool_at(3, 1, 0, 0) + when last = pool_at(3, 1, 0, 3) + then first == 8.0 and pool_at(3, 1, 0, 1) == 8.0 and pool_at(3, 1, 0, 2) == 9.0 and last == 9.0 + + test backward_basic_case + given at_max = backward_at(5) + when elsewhere = backward_at(0) + then at_max == 1.0 and elsewhere == 0.0 + + // Each window's gradient lands on its argmax only: the sum is conserved + test backward_gradient_propagation + given total = backward_at(5) + backward_at(6) + backward_at(13) + backward_at(11) + when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) + then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + + invariant maxpool_output_size_formula + assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2 diff --git a/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 b/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 new file mode 100644 index 0000000000..f26b20b6c6 --- /dev/null +++ b/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-maxpool.t27 -- max pooling: keep the largest value of each window, and where it was +; Source of truth for public/widgets/nn-maxpool/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-maxpool/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 11 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks one of four window and stride pairs and taps an output. Outputs and +; argmax indices are pool_at(kernel, stride, 0 or 1, i); for 2 x 2 stride 2 the gradient view is +; backward_at(i), the spec's output gradients 1, 2, 3, 4. + +; WHAT IT DOES NOT CLAIM: the grid is the spec's fixture, repeated as K_INPUT; the outputs and +; argmax come from the compiled fn, so a K_INPUT that drifted would show a max that is not in its +; window. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_maxpool; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-maxpool"; +pub const TITLE : str = "Max pooling: what a network keeps when it shrinks a picture"; +pub const DESCRIPTION : str = "Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell."; +pub const IMAGE_ALT : str = "Max-pool card, 2 x 2 windows with stride 2: the spec's 4 x 4 grid in pink and green, with cell 13 (value 9) outlined inside its window; the 2 x 2 output reads 4, 8, 9, -2 with 9 outlined. Tiles read max 9, argmax 13, output 2 x 2 and gradient at the max 3."; +pub const HOOK : str = "On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2; their gradients land on cells 5, 6, 13 and 11 and nowhere else."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SIDE : u8 = 4; +pub const K_INPUT : [16]i8 = [1, 2, 5, 6, 3, 4, 8, 7, 0, -1, -3, -2, -4, 9, -6, -5]; +pub const K_KERNELS : [4]u8 = [2, 3, 2, 4]; +pub const K_STRIDES : [4]u8 = [2, 1, 1, 1]; +pub const K_OUT_SIDES : [4]u8 = [2, 2, 3, 1]; +pub const K_PRESET_CFG : [3]u8 = [0, 1, 2]; +pub const K_PRESET_CELL : [3]u8 = [2, 0, 4]; +pub const K_PRESET_GRAD : [3]u8 = [0, 0, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["2 x 2, stride 2", "3 x 3, stride 1", "2 x 2, stride 1"]; +pub const SAY_ASK : str = "What does a network keep when it shrinks a picture?"; +pub const SAY_CONFIG : str = "window, stride"; +pub const SAY_CONFIG_NAMES : [4]str = ["2 x 2 / 2", "3 x 3 / 1", "2 x 2 / 1", "4 x 4 / 1"]; +pub const SAY_SHOW_GRAD : str = "show the gradient (2 x 2 / 2)"; +pub const SAY_IN_LABEL : str = "The spec's 4 x 4 input, the max of the window outlined"; +pub const SAY_GRAD_LABEL : str = "The gradient each input receives"; +pub const SAY_OUT_LABEL : str = "The output: tap a cell"; +pub const SAY_MAX : str = "max"; +pub const SAY_ARGMAX : str = "from cell"; +pub const SAY_OUT_SIDE : str = "output"; +pub const SAY_GRAD_AT_MAX : str = "gradient there"; +pub const SAY_NO_GRAD : str = "2 x 2 / 2 only"; +pub const SAY_NOTE : str = "A max pool forgets every value but one per window, which makes the network care less about exactly where a feature sits. In backpropagation the whole gradient of a window goes to its maximum."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/maxpool2d_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test every_output_side_follows_from_kernel_and_stride { + assert K_OUT_SIDES[0] * K_STRIDES[0] + K_KERNELS[0] - K_STRIDES[0] == K_SIDE; + assert K_OUT_SIDES[1] * K_STRIDES[1] + K_KERNELS[1] - K_STRIDES[1] == K_SIDE; + assert K_OUT_SIDES[2] * K_STRIDES[2] + K_KERNELS[2] - K_STRIDES[2] == K_SIDE; + assert K_OUT_SIDES[3] * K_STRIDES[3] + K_KERNELS[3] - K_STRIDES[3] == K_SIDE; +} + +test the_grid_is_the_spec_fixture { + assert K_INPUT[5] == 4; + assert K_INPUT[6] == 8; + assert K_INPUT[13] == 9; + assert K_INPUT[11] + 2 == 0; + assert K_OUT_SIDES[2] * K_OUT_SIDES[2] <= 9; +} diff --git a/apps/website/public/widgets/nn-maxpool/tool.js b/apps/website/public/widgets/nn-maxpool/tool.js new file mode 100644 index 0000000000..7828965276 --- /dev/null +++ b/apps/website/public/widgets/nn-maxpool/tool.js @@ -0,0 +1,44 @@ +// nn-maxpool/tool.js -- lesson 11 of neural-networks: what a network keeps when it shrinks a +// picture. Max pooling keeps the largest value of each window and remembers where it was; learning +// then sends each window's gradient to that one cell. Every output and argmax is pool_at, every +// gradient backward_at of gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27, compiled to wasm +// (./logic.js), on the spec's 4 x 4 fixture (K_INPUT, held equal to it by the tests below the spec). +// Words are SAY_ and numbers K_ constants of specs/widgets/nn-maxpool.t27. +import { backwardAt, poolAt } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, root, say, source, tiles, tone } from '../nn-kit.js' + +const SIDE = K('K_SIDE', 4) +const INPUT = K('K_INPUT', []) +const KS = K('K_KERNELS', []), ST = K('K_STRIDES', []), OUT = K('K_OUT_SIDES', []) +const ctl = controls([ + { key: 'cfg', label: say('SAY_CONFIG'), kind: 'choice', options: W.SAY_CONFIG_NAMES ?? [] }, + { key: 'cell', kind: 'hidden', min: 0, max: 8 }, + { key: 'grad', label: say('SAY_SHOW_GRAD'), kind: 'toggle' }, +], { names: W.SAY_PRESET_NAMES, values: { cfg: K('K_PRESET_CFG', []), cell: K('K_PRESET_CELL', []), grad: K('K_PRESET_GRAD', []) } }, draw) + +const img = canvas('nn-heat', say('SAY_IN_LABEL')) +const out = canvas('nn-heat', say('SAY_OUT_LABEL')) +const stat = el('div') +const inLabel = el('p', { class: 'dk-label' }) +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('div', { class: 'nn-two' }, el('div', {}, inLabel, img), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const k = KS[s.cfg], st = ST[s.cfg], n = OUT[s.cfg] + const cell = Math.min(s.cell, n * n - 1) + const oy = Math.floor(cell / n), ox = cell % n + const inWin = (r, c) => r >= oy * st && r < oy * st + k && c >= ox * st && c < ox * st + k + const arg = poolAt(k, st, 1, cell) + // The gradient path exists for the spec's 2 x 2, stride 2 case only (backward_at). + const grad = !!s.grad && s.cfg === 0 + inLabel.textContent = grad ? say('SAY_GRAD_LABEL') : say('SAY_IN_LABEL') + heat(img, { rows: SIDE, cols: SIDE, value: (r, c) => (grad ? backwardAt(r * SIDE + c) : INPUT[r * SIDE + c]), color: (v) => tone(v, 9), w: 400, cell: 92, fmt: (v) => fmt(v, 0), mark: (r, c) => (r * SIDE + c === arg ? 'on' : inWin(r, c) ? '' : 'dim') }) + heat(out, { rows: n, cols: n, value: (r, c) => poolAt(k, st, 0, r * n + c), color: (v) => tone(v, 9), w: 400, cell: Math.min(150, 300 / n), fmt: (v) => fmt(v, 0), mark: (r, c) => (r * n + c === cell ? 'on' : ''), onTap: (r, c) => ctl.set('cell', r * n + c) }) + stat.replaceChildren(tiles([ + { label: say('SAY_MAX'), value: fmt(poolAt(k, st, 0, cell), 0), tone: 0 }, + { label: say('SAY_ARGMAX'), value: fmt(arg, 0), tone: 1 }, + { label: say('SAY_OUT_SIDE'), value: `${n} x ${n}`, tone: 2 }, + { label: say('SAY_GRAD_AT_MAX'), value: s.cfg === 0 ? fmt(backwardAt(arg), 0) : say('SAY_NO_GRAD'), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-mse/card.png b/apps/website/public/widgets/nn-mse/card.png new file mode 100644 index 0000000000000000000000000000000000000000..433a46d3dd597d1290659c4140fc75cf77f6dde5 GIT binary patch literal 43230 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 + + + + + +Mean squared error: how wrong a guess is, as one number · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Mean squared error: how wrong a guess is, as one number

+

Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/loss/mse_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 13 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-mse/logic.js b/apps/website/public/widgets/nn-mse/logic.js new file mode 100644 index 0000000000..7a297bf67b --- /dev/null +++ b/apps/website/public/widgets/nn-mse/logic.js @@ -0,0 +1,32 @@ +// Generated by scripts/t27-logic.mjs from mse_loss.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 6dac9977868ce7ef5248582376372fdfb66261c8e2ced313e57aa48069b48cf0 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-mse/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABFANgAAF9YAR9fX1/AX1gA319fQF9AwQDAAECBAUBcAEBAQUDAQARBgkBfwFBgIDAAAsHOQQGbWVtb3J5AgANdDI3X21zZV9lbXB0eQAAD3QyN19tc2VfZ3JhZF9hdAABCnQyN19tc2VfYXQAAgqoAgMHAEMAAAAAC5sBAQJ/I4CAgIAAQSBrIgQkgICAgABBACEFIARBGGpBADYCACAEQgA3AxAgBCACOAIMIAQgATgCCCAEIAA4AgQCQANAIAVBDEYNASAEQRBqIAVqIARBBGogBWoqAgAgBUGAgMCAAGoqAgCTQ6uqKj+UOAIAIAVBBGohBQwACwsgBEEQaiADQQJ0aioCACECIARBIGokgICAgAAgAguAAQECfyOAgICAAEEQayIDJICAgIAAIAMgAjgCDCADIAE4AgggAyAAOAIEQwAAAAAhAkEAIQQCQANAIARBDEYNASACIANBBGogBGoqAgAgBEGAgMCAAGoqAgCTIgEgAZSSIQIgBEEEaiEEDAALCyADQRBqJICAgIAAIAJDAABAQJULCxUBAEGAgMAACwwAAIA/AAAAQAAAQEA="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function mseAt(p0, p1, p2) { + return W.t27_mse_at(p0, p1, p2); +} +function mseGradAt(p0, p1, p2, index) { + return W.t27_mse_grad_at(p0, p1, p2, int(index, 0, 4294967295, "mse_grad_at.index")); +} +function mseEmpty() { + return W.t27_mse_empty(); +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward"]); +export { + __NOT_LOWERED__, + mseAt, + mseEmpty, + mseGradAt +}; diff --git a/apps/website/public/widgets/nn-mse/logic.t27 b/apps/website/public/widgets/nn-mse/logic.t27 new file mode 100644 index 0000000000..f748e4e61b --- /dev/null +++ b/apps/website/public/widgets/nn-mse/logic.t27 @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Penalizes large errors more heavily | φ² + 1/φ² = 3 | TRINITY +// Restored 2026-10-05 from trinity specs/algo/mse_loss.tri: the port kept only +// the first parameter and returned void, so forward computed a value and +// threw it away, and every test asserted `result != undefined`. + +module MseLoss; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + // reduction: "mean", "sum" or "none" (from the .tri). forward below is the + // .tri's mean; the field is carried, not yet read. + pub const MSELossConfig = struct { + reduction : []const u8, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // forward(predictions, targets) -> mean((predictions - targets)^2); 0 for n = 0 + fn forward(predictions: []const f32, targets: []const f32) -> f32 { + if (predictions.len == 0) { + return 0.0; + } + var sum_loss : f32 = 0.0; + var i : usize = 0; + while (i < predictions.len) { + const diff = predictions[i] - targets[i]; + sum_loss = sum_loss + diff * diff; + i = i + 1; + } + return sum_loss / (predictions.len as f32); + } + + // backward: grad_input[i] = 2 (predictions[i] - targets[i]) / n + fn backward(predictions: []const f32, targets: []const f32, grad_input: []f32) -> void { + if (predictions.len == 0) { + return; + } + const scale = 2.0 / (predictions.len as f32); + var i : usize = 0; + while (i < predictions.len) { + grad_input[i] = scale * (predictions[i] - targets[i]); + i = i + 1; + } + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests + // ═══════════════════════════════════════════════════════════ + + fn mse_at(p0: f32, p1: f32, p2: f32) -> f32 { + const predictions : [3]f32 = [p0, p1, p2]; + const targets : [3]f32 = [1.0, 2.0, 3.0]; + return forward(&predictions, &targets); + } + + fn mse_grad_at(p0: f32, p1: f32, p2: f32, index: usize) -> f32 { + const predictions : [3]f32 = [p0, p1, p2]; + const targets : [3]f32 = [1.0, 2.0, 3.0]; + var grads : [3]f32 = [0.0] ** 3; + backward(&predictions, &targets, &grads); + return grads[index]; + } + + fn mse_empty() -> f32 { + const none : [0]f32 = []; + return forward(&none, &none); + } + + test forward_zero_on_exact_match + given result = mse_at(1.0, 2.0, 3.0) + when also = mse_empty() + then result == 0.0 and also == 0.0 + + // errors (0.5, -1, 2): (0.25 + 1 + 4) / 3 = 1.75 + test forward_basic_case + given result = mse_at(1.5, 1.0, 5.0) + when flipped = mse_at(0.5, 3.0, 1.0) + then @abs(result - 1.75) < 0.000001 and @abs(flipped - result) < 0.000001 + + test backward_matches_finite_difference + given slope = (mse_at(1.5, 1.001, 5.0) - mse_at(1.5, 0.999, 5.0)) / 0.002 + when result = mse_grad_at(1.5, 1.0, 5.0, 1) + then @abs(result - slope) < 0.001 and @abs(result - (-2.0 / 3.0)) < 0.000001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants + // ═══════════════════════════════════════════════════════════ + + invariant mse_zero_at_target + assert mse_at(1.0, 2.0, 3.0) == 0.0 diff --git a/apps/website/public/widgets/nn-mse/nn-mse.t27 b/apps/website/public/widgets/nn-mse/nn-mse.t27 new file mode 100644 index 0000000000..1f045e1fbd --- /dev/null +++ b/apps/website/public/widgets/nn-mse/nn-mse.t27 @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-mse.t27 -- mean squared error: how wrong a guess is, as one number +; Source of truth for public/widgets/nn-mse/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-mse/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/mse_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 13 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader moves three predictions from -1 to 5. The loss is mse_at(p0, p1, p2) +; against the spec's targets (1, 2, 3), each gradient mse_grad_at, and the bowl mse_at over p0. + +; WHAT IT DOES NOT CLAIM: the targets are the spec's fixture, repeated as K_TARGETS; every loss and +; gradient comes from the compiled fn. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_mse; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-mse"; +pub const TITLE : str = "Mean squared error: how wrong a guess is, as one number"; +pub const DESCRIPTION : str = "Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target."; +pub const IMAGE_ALT : str = "MSE card: predictions 1.5, 2 and 2 against targets 1, 2, 3 drawn as white rings with green dots, red dashed misses and pink gradient arrows. Below, the loss as prediction 0 moves is a gold parabola with its cursor at 1.5. Tiles read loss 0.4167, gradients 0.333 0.000 -0.667, loss at the targets 0.0000 and misses of 1 and 2 costing 0.333 and 1.333."; +pub const HOOK : str = "A miss of 1 costs 1 / 3 of the mean; a miss of 2 costs 4 / 3. Squaring is what makes MSE fear large errors and shrug at small ones."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/mse_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 13 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_TARGETS : [3]u8 = [1, 2, 3]; +pub const K_P_LO_C : i16 = -100; +pub const K_P_HI_C : u16 = 500; +pub const K_P_TICKS : [7]i8 = [-1, 0, 1, 2, 3, 4, 5]; +pub const K_LOSS_HI_C : u16 = 600; +pub const K_LOSS_TICKS : [4]u8 = [0, 2, 4, 6]; +pub const K_PRESET_P0_C : [4]i16 = [150, 100, 300, -100]; +pub const K_PRESET_P1_C : [4]u16 = [200, 200, 200, 400]; +pub const K_PRESET_P2_C : [4]u16 = [200, 300, 300, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["1.5, 2, 2", "On target", "One miss of 2", "All wrong"]; +pub const SAY_ASK : str = "How wrong is a guess, as one number?"; +pub const SAY_PRED : str = "prediction"; +pub const SAY_TARGET : str = "target"; +pub const SAY_GRAD : str = "minus the gradient"; +pub const SAY_MISS_LABEL : str = "Each prediction, its target and the step the gradient asks for"; +pub const SAY_BOWL_LABEL : str = "The loss as prediction 0 moves, the others held"; +pub const SAY_BOWL : str = "Drag along the bowl: the loss as prediction 0 alone moves."; +pub const SAY_LOSS : str = "loss"; +pub const SAY_GRADS : str = "gradients"; +pub const SAY_AT_TARGET : str = "loss on target"; +pub const SAY_DOUBLE : str = "miss of 1 / of 2"; +pub const SAY_NOTE : str = "The gradient of each prediction is 2 (p - t) / n: the further off, the harder the pull. Gradient descent follows it downhill into the bottom of the bowl."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/mse_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_targets_are_the_spec_fixture { + assert K_TARGETS[0] == 1; + assert K_TARGETS[1] == 2; + assert K_TARGETS[2] == 3; +} + +test the_presets_stay_in_range { + assert K_PRESET_P0_C[3] >= K_P_LO_C; + assert K_PRESET_P1_C[3] <= K_P_HI_C; + assert K_PRESET_P0_C[1] == K_TARGETS[0] * 100; +} diff --git a/apps/website/public/widgets/nn-mse/tool.js b/apps/website/public/widgets/nn-mse/tool.js new file mode 100644 index 0000000000..d59ee9ac54 --- /dev/null +++ b/apps/website/public/widgets/nn-mse/tool.js @@ -0,0 +1,46 @@ +// nn-mse/tool.js -- lesson 13 of neural-networks: how wrong is a guess, as one number. Mean squared +// error averages the squared misses, so a miss twice as far costs four times as much, and its +// gradient points each prediction back at its target. Every value is mse_at or mse_grad_at of +// gHashTag/t27 specs/ml/loss/mse_loss.t27, compiled to wasm (./logic.js), against the spec's targets +// (1, 2, 3) (K_TARGETS, held equal by the widget's tests). Words are SAY_ and numbers K_ constants of +// specs/widgets/nn-mse.t27. +import { mseAt, mseGradAt } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, svgEl, tiles } from '../nn-kit.js' + +const T = K('K_TARGETS', []) +const P0 = centi(K('K_P_LO_C', -100)), P1 = centi(K('K_P_HI_C', 500)) +const pred = (key, i) => ({ key, label: `${say('SAY_PRED')} ${i}`, min: P0, max: P1, step: 0.05, fmt: (v) => fmt(v, 2) }) +const ctl = controls([pred('p0', 0), pred('p1', 1), pred('p2', 2)], + { names: W.SAY_PRESET_NAMES, values: { p0: K('K_PRESET_P0_C', []).map(centi), p1: K('K_PRESET_P1_C', []).map(centi), p2: K('K_PRESET_P2_C', []).map(centi) } }, draw) + +const misses = canvas('nn-curve', say('SAY_MISS_LABEL')) +const bowl = canvas('nn-curve', say('SAY_BOWL_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, misses, legend([[say('SAY_TARGET'), '#ffffff'], [say('SAY_PRED'), COLORS[0]], [say('SAY_GRAD'), COLORS[3]]]), el('p', { class: 'dk-note' }, say('SAY_BOWL')), bowl, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const p = [s.p0, s.p1, s.p2] + misses.replaceChildren() + const m = plot(misses, { w: 640, h: 300, x0: -0.5, x1: 2.5, y0: P0, y1: P1, xticks: [0, 1, 2], yticks: K('K_P_TICKS', []), xfmt: (i) => `${say('SAY_PRED')} ${i}`, left: 40 }) + for (let i = 0; i < 3; i++) { + const g = mseGradAt(s.p0, s.p1, s.p2, i) + misses.append(svgEl('line', { x1: m.x(i), x2: m.x(i), y1: m.clampY(T[i]), y2: m.clampY(p[i]), stroke: COLORS[6], 'stroke-width': 3, 'stroke-dasharray': '4 4' })) + misses.append(svgEl('line', { x1: m.x(i) + 26, x2: m.x(i) + 26, y1: m.clampY(p[i]), y2: m.clampY(p[i] - g), stroke: COLORS[3], 'stroke-width': 4 })) + misses.append(svgEl('circle', { cx: m.x(i), cy: m.clampY(T[i]), r: 8, fill: 'none', stroke: '#fff', 'stroke-width': 3 })) + misses.append(svgEl('circle', { cx: m.x(i), cy: m.clampY(p[i]), r: 9, fill: COLORS[0] })) + } + bowl.replaceChildren() + const o = { w: 640, h: 280, x0: P0, x1: P1, y0: 0, y1: centi(K('K_LOSS_HI_C', 600)), xticks: K('K_P_TICKS', []), yticks: K('K_LOSS_TICKS', []), xlabel: `${say('SAY_PRED')} 0` } + const b = plot(bowl, o) + b.line(sample((x) => mseAt(x, s.p1, s.p2), P0, P1), COLORS[1], 3) + cursor(bowl, b, s.p0, [[mseAt(s.p0, s.p1, s.p2), COLORS[1]]]) + dragX(bowl, b, o, (x) => ctl.set('p0', x)) + stat.replaceChildren(tiles([ + { label: say('SAY_LOSS'), value: fmt(mseAt(s.p0, s.p1, s.p2), 4), tone: 1 }, + { label: say('SAY_GRADS'), value: [0, 1, 2].map((i) => fmt(mseGradAt(s.p0, s.p1, s.p2, i), 3)).join(' '), tone: 3 }, + { label: say('SAY_AT_TARGET'), value: fmt(mseAt(T[0], T[1], T[2]), 4), tone: 0 }, + { label: say('SAY_DOUBLE'), value: `${fmt(mseAt(T[0] + 1, T[1], T[2]), 3)} / ${fmt(mseAt(T[0] + 2, T[1], T[2]), 3)}`, tone: 6 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-positions/card.png b/apps/website/public/widgets/nn-positions/card.png new file mode 100644 index 0000000000000000000000000000000000000000..1b8679d659bc22b374820eb6e18af236d0a1f8d1 GIT binary patch literal 80432 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

V*OYZhzh5t`?=T#by;_W|&fz2b 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-positions/index.html b/apps/website/public/widgets/nn-positions/index.html new file mode 100644 index 0000000000..84f33234e6 --- /dev/null +++ b/apps/website/public/widgets/nn-positions/index.html @@ -0,0 +1,47 @@ + + + + + + +Positional encoding: how a transformer knows word order · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +

+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/transformer/positional_encoding.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 25 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-positions/logic.js b/apps/website/public/widgets/nn-positions/logic.js new file mode 100644 index 0000000000..71c5913779 --- /dev/null +++ b/apps/website/public/widgets/nn-positions/logic.js @@ -0,0 +1,28 @@ +// Generated by scripts/t27-logic.mjs from positional_encoding.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 2c979472dc128223ad4645c13b2776435ddf344ea29ffa5ed2e6c0b0056d3f09 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-positions/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function invFreq(pair, dModel) { + return W.t27_inv_freq(int(pair, 0, 4294967295, "inv_freq.pair"), int(dModel, 0, 4294967295, "inv_freq.d_model")); +} +function pe(pos, dim) { + return W.t27_pe(int(pos, 0, 4294967295, "pe.pos"), int(dim, 0, 4294967295, "pe.dim")); +} +const __NOT_LOWERED__ = Object.freeze(["forward"]); +export { + __NOT_LOWERED__, + invFreq, + pe +}; diff --git a/apps/website/public/widgets/nn-positions/logic.t27 b/apps/website/public/widgets/nn-positions/logic.t27 new file mode 100644 index 0000000000..11ed097e9a --- /dev/null +++ b/apps/website/public/widgets/nn-positions/logic.t27 @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Uses sin/cos at different frequencies for each dimension | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward read an undeclared `d_model`, called `math::pow` / `math::sin` / +// `math::cos`, computed each encoding into a local and dropped it, and grew the +// frequency with the dimension where Vaswani et al. (2017) shrink it. It now +// writes the sinusoidal encoding +// PE(pos, 2i) = sin(pos / 10000^(2i / d)), PE(pos, 2i + 1) = cos(pos / 10000^(2i / d)) +// for each position into a positions x d_model buffer. + +module PositionalEnc; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_MAX_LEN : u32 = 2048; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const PosEncConfig = struct { + d_model : u32, + max_len : u32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // 1 / 10000^(2i / d) = exp(-(2i / d) ln 10000) + fn inv_freq(pair: u32, d_model: u32) -> f32 { + return exp(-(@as(f32, @floatFromInt(2 * pair)) / @as(f32, @floatFromInt(d_model))) * log(@as(f32, 10000.0))); + } + + fn forward(positions: []const u32, config: PosEncConfig, out: []f32) -> void { + var p : usize = 0; + while (p < positions.len) { + const pos : f32 = @as(f32, @floatFromInt(positions[p])); + var dim : u32 = 0; + while (dim < config.d_model) { + const angle = pos * inv_freq(dim / 2, config.d_model); + if (dim % 2 == 0) { + out[p * config.d_model + dim] = sin(angle); + } else { + out[p * config.d_model + dim] = cos(angle); + } + dim = dim + 1; + } + p = p + 1; + } + } + + // PE(pos, dim) for d_model 8 + fn pe(pos: u32, dim: usize) -> f32 { + const positions : [1]u32 = [pos]; + var out : [8]f32 = [9.0] ** 8; + forward(&positions, PosEncConfig{ .d_model = 8, .max_len = DEFAULT_MAX_LEN }, &out); + return out[dim]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // pos 1, d 8: dims 0/1 use frequency 1, dims 2/3 use 1/10 (10000^(2/8) = 10) + test forward_basic_case + given s0 = pe(1, 0) + when s2 = pe(1, 2) + then @abs(s0 - 0.8414710) < 0.000001 and @abs(pe(1, 1) - 0.5403023) < 0.000001 and @abs(s2 - 0.0998334) < 0.000001 and @abs(pe(1, 3) - 0.9950042) < 0.000001 + + // Position 0 encodes as (0, 1, 0, 1, ...) + test forward_simple + given s = pe(0, 6) + when c = pe(0, 7) + then s == 0.0 and c == 1.0 + + // Each sin/cos pair lies on the unit circle + test forward_pairs_are_unit_vectors + given p = pe(37, 2) * pe(37, 2) + pe(37, 3) * pe(37, 3) + then @abs(p - 1.0) < 0.000001 + + invariant positional_encoding_max_len_is_positive + assert DEFAULT_MAX_LEN > 0 diff --git a/apps/website/public/widgets/nn-positions/nn-positions.t27 b/apps/website/public/widgets/nn-positions/nn-positions.t27 new file mode 100644 index 0000000000..1d38dcee64 --- /dev/null +++ b/apps/website/public/widgets/nn-positions/nn-positions.t27 @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-positions.t27 -- sinusoidal positional encoding: stripes and clocks +; Source of truth for public/widgets/nn-positions/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-positions/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/transformer/positional_encoding.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 25 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the position from 0 to 200. Every stripe, hand and value is pe(pos, +; dim) of the spec at d_model 8; the speeds are inv_freq(pair, 8). + +; WHAT IT DOES NOT CLAIM: d_model 8 shows the pattern; a real model uses hundreds of dimensions, and +; many now learn or rotate positions instead. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_positions; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-positions"; +pub const TITLE : str = "Positional encoding: how a transformer knows word order"; +pub const DESCRIPTION : str = "Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows."; +pub const IMAGE_ALT : str = "Positional-encoding card at position 5: four clocks with coloured hands, the fastest turned far round, the slowest still pointing up. Below, a stripe chart of 48 positions by 8 dimensions in pink and green: the left columns flicker fast, the right ones barely change. Tiles read the 8 values and the 4 speeds 1, 0.1, 0.01, 0.001."; +pub const HOOK : str = "Position 5 is (-0.959, 0.284, 0.479, 0.878, 0.050, 0.999, 0.005, 1.000). Four clocks at speeds 1, 0.1, 0.01 and 0.001 give each position its own reading."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/transformer/positional_encoding.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 25 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_D_MODEL : u8 = 8; +pub const K_ROWS : u8 = 48; +pub const K_POS_HI : u8 = 200; +pub const K_PRESET_POS : [4]u8 = [5, 0, 1, 37]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Position 5", "Position 0", "Position 1", "Position 37"]; +pub const SAY_ASK : str = "Attention sees a set of words. How does it know their order?"; +pub const SAY_POS : str = "position"; +pub const SAY_STRIPES_LABEL : str = "pe(pos, dim) for positions 0 to 47 (rows) and the 8 dimensions"; +pub const SAY_CLOCKS_LABEL : str = "Each sin and cos pair as a clock hand, and its speed"; +pub const SAY_PAIR : str = "pair"; +pub const SAY_VECTOR : str = "the 8 numbers"; +pub const SAY_FAST : str = "fastest pair"; +pub const SAY_SLOW : str = "slowest pair"; +pub const SAY_FREQS : str = "speeds"; +pub const SAY_NOTE : str = "A shift by k positions turns every clock by its own fixed angle, so the distance between two positions is visible to a dot product. Position 0 is (0, 1, 0, 1, ...)."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/transformer/positional_encoding.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test eight_dimensions_four_clocks { + assert K_D_MODEL == 8; + assert K_D_MODEL % 2 == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_POS[3] < K_ROWS; + assert K_PRESET_POS[1] == 0; + assert K_POS_HI > K_ROWS; +} diff --git a/apps/website/public/widgets/nn-positions/tool.js b/apps/website/public/widgets/nn-positions/tool.js new file mode 100644 index 0000000000..d78debd144 --- /dev/null +++ b/apps/website/public/widgets/nn-positions/tool.js @@ -0,0 +1,42 @@ +// nn-positions/tool.js -- lesson 25 of neural-networks: how a transformer knows the order of words. +// Each position gets a vector of sines and cosines at frequencies falling by 10000^(2i/d): the fast +// dimensions flicker, the slow ones barely move, and together every position gets its own pattern. +// Every stripe, hand and tile is pe(pos, dim) of gHashTag/t27 specs/ml/transformer/ +// positional_encoding.t27, compiled to wasm (./logic.js), d_model 8. Words are SAY_ and numbers K_ +// constants of specs/widgets/nn-positions.t27. +import { invFreq, pe } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, root, say, source, svgEl, tiles, tone } from '../nn-kit.js' + +const D = K('K_D_MODEL', 8), ROWS = K('K_ROWS', 48), PMAX = K('K_POS_HI', 200) +const ctl = controls([ + { key: 'pos', label: say('SAY_POS'), min: 0, max: PMAX }, +], { names: W.SAY_PRESET_NAMES, values: { pos: K('K_PRESET_POS', []) } }, draw) + +const stripes = canvas('nn-heat', say('SAY_STRIPES_LABEL')) +const clocks = canvas('nn-clocks', say('SAY_CLOCKS_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('p', { class: 'dk-label' }, say('SAY_CLOCKS_LABEL')), clocks, stat, el('p', { class: 'dk-label' }, say('SAY_STRIPES_LABEL')), stripes, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + // Stripes: positions down, dimensions across; the selected position's row is outlined when it is shown. + heat(stripes, { rows: ROWS, cols: D, value: (r, c) => pe(r, c), color: (v) => tone(v, 1), colLabels: [...Array(D)].map((_, c) => `${c % 2 ? 'cos' : 'sin'}${c >> 1}`), w: 640, cell: 76, cellH: 9, fmt: null, mark: (r) => (r === s.pos ? 'on' : '') }) + // Clocks: each sin/cos pair is a hand on a circle, turning at its own speed. + clocks.replaceChildren() + clocks.setAttribute('viewBox', '0 0 640 190') + for (let k = 0; k < D / 2; k++) { + const cx = 80 + k * 160, cy = 92, R = 62 + const sx = pe(s.pos, 2 * k), cs = pe(s.pos, 2 * k + 1) + clocks.append(svgEl('circle', { cx, cy, r: R, fill: '#020403', stroke: COLORS[k + 2], 'stroke-width': 2, opacity: 0.9 })) + clocks.append(svgEl('line', { x1: cx, y1: cy, x2: cx + sx * R, y2: cy - cs * R, stroke: COLORS[k + 2], 'stroke-width': 5, 'stroke-linecap': 'round' })) + clocks.append(svgEl('circle', { cx: cx + sx * R, cy: cy - cs * R, r: 7, fill: COLORS[k + 2] })) + clocks.append(svgEl('text', { x: cx, y: 182, class: 'dk-tick', 'text-anchor': 'middle' }, `${say('SAY_PAIR')} ${k}: ${fmt(invFreq(k, D), 4)}`)) + } + stat.replaceChildren(tiles([ + { label: say('SAY_VECTOR'), value: [...Array(D)].map((_, c) => fmt(pe(s.pos, c), 2)).join(' '), tone: 0 }, + { label: say('SAY_FAST'), value: `${fmt(pe(s.pos, 0), 3)}, ${fmt(pe(s.pos, 1), 3)}`, tone: 2 }, + { label: say('SAY_SLOW'), value: `${fmt(pe(s.pos, D - 2), 4)}, ${fmt(pe(s.pos, D - 1), 4)}`, tone: 3 }, + { label: say('SAY_FREQS'), value: [...Array(D / 2)].map((_, k) => fmt(invFreq(k, D), 3)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-ppo/card.png b/apps/website/public/widgets/nn-ppo/card.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc7fc183c23c82cf29921aae5d43722015359e5 GIT binary patch literal 41598 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 Wg(pZ+K3?z(OjpbBM6t%1OaBFXq3>z{ literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-ppo/index.html b/apps/website/public/widgets/nn-ppo/index.html new file mode 100644 index 0000000000..d88a7cafb9 --- /dev/null +++ b/apps/website/public/widgets/nn-ppo/index.html @@ -0,0 +1,47 @@ + + + + + + +PPO: how an agent learns from reward without lurching · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

PPO: how an agent learns from reward without lurching

+

Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/rl/ppo_clip_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 27 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-ppo/logic.js b/apps/website/public/widgets/nn-ppo/logic.js new file mode 100644 index 0000000000..372de11955 --- /dev/null +++ b/apps/website/public/widgets/nn-ppo/logic.js @@ -0,0 +1,43 @@ +// Generated by scripts/t27-logic.mjs from ppo_clip_loss.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: d0883efe249316ba0beddd1063ef00c8546c8c982d5636a79971f30a3a1bf855 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-ppo/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function computeRatio(newLogProb, oldLogProb) { + return W.t27_compute_ratio(newLogProb, oldLogProb); +} +function clippedSurrogate(ratio, advantage, clipEpsilon) { + return W.t27_clipped_surrogate(ratio, advantage, clipEpsilon); +} +function policyLossOf(r0, r1, r2) { + return W.t27_policy_loss_of(r0, r1, r2); +} +function entropyLossOf() { + return W.t27_entropy_loss_of(); +} +function valueLossOf(p0) { + return W.t27_value_loss_of(p0); +} +function validInput() { + return W.t27_valid_input(); +} +function totalLoss(policyLossValue, valueLossValue, entropyLossValue, valueLossCoef) { + return W.t27_total_loss(policyLossValue, valueLossValue, entropyLossValue, valueLossCoef); +} +const __NOT_LOWERED__ = Object.freeze(["policy_loss", "entropy_loss", "value_loss"]); +export { + __NOT_LOWERED__, + clippedSurrogate, + computeRatio, + entropyLossOf, + policyLossOf, + totalLoss, + validInput, + valueLossOf +}; diff --git a/apps/website/public/widgets/nn-ppo/logic.t27 b/apps/website/public/widgets/nn-ppo/logic.t27 new file mode 100644 index 0000000000..72d30bb304 --- /dev/null +++ b/apps/website/public/widgets/nn-ppo/logic.t27 @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Probability ratio between policies | φ² + 1/φ² = 3 | TRINITY + +// #8980: written with `let x = if ... {}` and `for i in 0..n`, so it never compiled. +// Three formulas were wrong, and their tests pinned the wrong values: +// - compute_ratio returned log pi_new - log pi_old; the ratio is exp of that. +// - clipped_surrogate returned clip(r) A; PPO's term is min(r A, clip(r) A), so +// r = 1.1 inside the clip range gives 2.2, not 2.4. +// - policy_loss returned the surrogate itself, a quantity to MAXIMISE; as a loss +// added to the value and entropy losses it is minus the mean surrogate. +// Each test now states the value PPO defines (Schulman et al., 2017). + +module PpoClipLoss; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_CLIP_EPSILON : f32 = 0.2; + const DEFAULT_ENTROPY_COEF : f32 = 0.01; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const PPOClipConfig = struct { + clip_epsilon : f32, + entropy_coef : f32, + value_clip_coef : f32, + }; + + pub const PPOBatch = struct { + states : [][]f32, + actions : [][]f32, + old_log_probs : []f32, + advantages : []f32, + returns : []f32, + values : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // r = pi_new / pi_old = exp(log pi_new - log pi_old) + fn compute_ratio(new_log_prob: f32, old_log_prob: f32) -> f32 { + return exp(new_log_prob - old_log_prob); + } + + // min(r A, clip(r, 1 - eps, 1 + eps) A) + fn clipped_surrogate(ratio: f32, advantage: f32, clip_epsilon: f32) -> f32 { + const clipped_ratio = @min(@max(ratio, 1.0 - clip_epsilon), 1.0 + clip_epsilon); + return @min(ratio * advantage, clipped_ratio * advantage); + } + + // -mean_t min(r_t A_t, clip(r_t) A_t): the loss gradient descent minimises + fn policy_loss(ratios: []const f32, advantages: []const f32, clip_epsilon: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < ratios.len) { + total = total + clipped_surrogate(ratios[i], advantages[i], clip_epsilon); + i = i + 1; + } + return -total / @as(f32, @floatFromInt(ratios.len)); + } + + // -coef * mean entropy: lower loss for a more exploratory policy + fn entropy_loss(entropies: []const f32, entropy_coef: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < entropies.len) { + total = total + entropies[i]; + i = i + 1; + } + return -entropy_coef * (total / @as(f32, @floatFromInt(entropies.len))); + } + + // mean 0.5 (target - (old + clip(pred - old, -c, c)))^2 + fn value_loss(predicted_values: []const f32, target_values: []const f32, old_values: []const f32, clip_coef: f32) -> f32 { + var total : f32 = 0.0; + var i : usize = 0; + while (i < predicted_values.len) { + const diff = @min(@max(predicted_values[i] - old_values[i], -clip_coef), clip_coef); + const err = target_values[i] - (old_values[i] + diff); + total = total + 0.5 * err * err; + i = i + 1; + } + return total / @as(f32, @floatFromInt(predicted_values.len)); + } + + fn policy_loss_of(r0: f32, r1: f32, r2: f32) -> f32 { + const ratios : [3]f32 = [r0, r1, r2]; + const advantages : [3]f32 = [2.0, 1.5, 3.0]; + return policy_loss(&ratios, &advantages, DEFAULT_CLIP_EPSILON); + } + + fn entropy_loss_of() -> f32 { + const entropies : [3]f32 = [0.5, 0.6, 0.4]; + return entropy_loss(&entropies, DEFAULT_ENTROPY_COEF); + } + + fn value_loss_of(p0: f32) -> f32 { + const predicted : [3]f32 = [p0, 2.0, 1.5]; + const target : [3]f32 = [1.1, 2.1, 1.6]; + const old : [3]f32 = [0.9, 1.9, 1.4]; + return value_loss(&predicted, &target, &old, 0.2); + } + + fn valid_input() -> f32 { + return DEFAULT_CLIP_EPSILON; + } + + // total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) → f32 + fn total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) -> f32 { + // Combine all loss components + return policy_loss_value + value_loss_coef * value_loss_value + entropy_loss_value; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test compute_ratio_basic_case + given + new_log_prob = 0.5 + old_log_prob = 0.3 + when result = compute_ratio(new_log_prob, old_log_prob) + then @abs(result - 1.2214028) < 0.000001 // exp(0.2); the old `== 0.2` was the log ratio + + test clipped_surrogate_basic_case + given + ratio = 1.1 + advantage = 2.0 + clip_epsilon = 0.2 + when result = clipped_surrogate(ratio, advantage, clip_epsilon) + then @abs(result - 1.1 * 2.0) < 0.000001 // inside [0.8, 1.2] the clip does nothing + + test clipped_surrogate_clipping_case + given + ratio = 1.5 // Above clip threshold of 1.2 + advantage = 2.0 + clip_epsilon = 0.2 + when result = clipped_surrogate(ratio, advantage, clip_epsilon) + then @abs(result - 1.2 * 2.0) < 0.000001 and clipped_surrogate(0.5, -1.0, 0.2) == -0.8 + + // min(r A, clip(r) A) = (2.0, 1.65, 2.7): the loss is -mean = -2.1166667. The old `> 0` was + // the surrogate's sign; a ratio pushed past the clip earns nothing more. + test policy_loss_basic_case + given result = policy_loss_of(1.0, 1.1, 0.9) + when pushed = policy_loss_of(1.0, 1.1, 3.0) + then result < 0.0 and @abs(result + 2.1166667) < 0.000001 and @abs(pushed - policy_loss_of(1.0, 1.1, 1.2)) < 0.000001 + + test entropy_loss_basic_case + given result = entropy_loss_of() + then result < 0.0 and @abs(result + 0.005) < 0.0000001 + + test value_loss_basic_case + given result = value_loss_of(1.0) + when clipped = value_loss_of(5.0) + then result > 0.0 and @abs(result - 0.005) < 0.0000001 and @abs(clipped - value_loss_of(1.1)) < 0.0000001 + + test total_loss_basic_case + given + policy_loss_value = 1.0 + value_loss_value = 0.5 + entropy_loss_value = -0.01 + value_loss_coef = 0.5 + when result = total_loss(policy_loss_value, value_loss_value, entropy_loss_value, value_loss_coef) + then @abs(result - (1.0 + 0.5 * 0.5 + (-0.01))) < 0.0000001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // 0 < clip_epsilon <= 1 (typically 0.1-0.3) + invariant ppo_clip_loss_constraint_0 + assert valid_input() > 0.0 and valid_input() <= 1.0 + + // entropy_coef >= 0 + invariant ppo_clip_loss_constraint_1 + assert DEFAULT_ENTROPY_COEF >= 0.0 + + // name: ppo_objective -- for A > 0 the surrogate stops growing at r = 1 + eps + invariant ppo_clip_loss_constraint_2 + assert clipped_surrogate(5.0, 1.0, 0.2) == 1.2 + + // name: probability_ratio -- equal log-probabilities give r = 1 + invariant ppo_clip_loss_constraint_3 + assert compute_ratio(0.3, 0.3) == 1.0 + + // "Schulman et al. (2017) - Proximal Policy Optimization Algorithms, arXiv:1707.06347": + // for A < 0 the surrogate stops falling at r = 1 - eps + invariant ppo_clip_loss_constraint_4 + assert clipped_surrogate(0.1, -1.0, 0.2) == -0.8 diff --git a/apps/website/public/widgets/nn-ppo/nn-ppo.t27 b/apps/website/public/widgets/nn-ppo/nn-ppo.t27 new file mode 100644 index 0000000000..f32a2aeb05 --- /dev/null +++ b/apps/website/public/widgets/nn-ppo/nn-ppo.t27 @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-ppo.t27 -- PPO's clipped surrogate: a reward that stops pulling +; Source of truth for public/widgets/nn-ppo/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-ppo/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/rl/ppo_clip_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 27 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags r from 0 to 2 and sets the advantage A from -2 to 2 and eps from +; 0.05 to 0.5. The green curve is clipped_surrogate(r, A, eps), the dashed one clipped_surrogate(r, +; A, 1000), which never clips here, and the tiles policy_loss_of on the spec's advantages (2, 1.5, +; 3). + +; WHAT IT DOES NOT CLAIM: the objective of one sample; PPO averages it over a batch, adds value and +; entropy terms (total_loss in the spec) and runs it for a few epochs per batch. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_ppo; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-ppo"; +pub const TITLE : str = "PPO: how an agent learns from reward without lurching"; +pub const DESCRIPTION : str = "Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling."; +pub const IMAGE_ALT : str = "PPO card at r = 1.5, A = 1, eps 0.2: the dashed gold raw objective is a straight line through the origin; the thick green clipped one follows it and turns flat at 1.2 from r = 1.2 on. Tiles read clipped 1.2000, raw 1.5000, the spec batch policy loss -2.1167 and the same batch at r = 1.5, -2.6000."; +pub const HOOK : str = "At r = 1.5 with advantage 1 and eps 0.2, the raw objective is 1.5 but PPO counts only 1.2. The clip is what keeps one update from breaking the policy."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/rl/ppo_clip_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 27 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_R_HI_C : u16 = 200; +pub const K_A_LO_C : i16 = -200; +pub const K_A_HI_C : u16 = 200; +pub const K_EPS_LO_C : u8 = 5; +pub const K_EPS_HI_C : u8 = 50; +pub const K_WIDE : u16 = 1000; +pub const K_Y_LO : i8 = -4; +pub const K_Y_HI : u8 = 4; +pub const K_Y_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_R_TICKS_C : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_BATCH_R_C : [3]u8 = [100, 110, 90]; +pub const K_PRESET_R_C : [4]u8 = [150, 50, 150, 80]; +pub const K_PRESET_A_C : [4]i16 = [100, -100, 200, -200]; +pub const K_PRESET_EPS_C : [4]u8 = [20, 20, 50, 10]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["r 1.5, A 1", "r 0.5, A -1", "r 1.5, A 2, eps 0.5", "r 0.8, A -2, eps 0.1"]; +pub const SAY_ASK : str = "How does an agent learn from reward without lurching?"; +pub const SAY_R : str = "ratio r = new / old"; +pub const SAY_A : str = "advantage A"; +pub const SAY_EPS : str = "clip eps"; +pub const SAY_PLOT_LABEL : str = "PPO's clipped objective and the raw r A as the ratio goes from 0 to 2"; +pub const SAY_CLIPPED : str = "PPO objective"; +pub const SAY_RAW : str = "raw r A"; +pub const SAY_BATCH : str = "spec batch loss"; +pub const SAY_BATCH_FAR : str = "same batch at r"; +pub const SAY_NOTE : str = "A positive advantage says the action was better than expected, so raise its probability; past 1 + eps there is no more credit for it. A negative one is clipped at 1 - eps the same way."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/rl/ppo_clip_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_wide_clip_never_clips_the_window { + assert K_WIDE * 100 > K_R_HI_C; + assert K_EPS_HI_C < 100; +} + +test the_presets_stay_in_range { + assert K_PRESET_R_C[0] <= K_R_HI_C; + assert K_PRESET_A_C[3] == K_A_LO_C; + assert K_PRESET_EPS_C[3] >= K_EPS_LO_C; + assert K_BATCH_R_C[0] == 100; +} diff --git a/apps/website/public/widgets/nn-ppo/tool.js b/apps/website/public/widgets/nn-ppo/tool.js new file mode 100644 index 0000000000..327cc2a0ad --- /dev/null +++ b/apps/website/public/widgets/nn-ppo/tool.js @@ -0,0 +1,40 @@ +// nn-ppo/tool.js -- lesson 27 of neural-networks: how an agent learns from reward without lurching. +// PPO scores a change in policy by min(r A, clip(r, 1 - eps, 1 + eps) A): once the probability +// ratio r has moved more than eps in the direction the advantage A rewards, the objective goes flat +// and stops pulling. Both curves and every tile are clipped_surrogate of gHashTag/t27 +// specs/ml/rl/ppo_clip_loss.t27, compiled to wasm (./logic.js); the dashed curve is the same fn with +// a clip range so wide (K_WIDE) it never clips. Words are SAY_ and numbers K_ constants of +// specs/widgets/nn-ppo.t27. +import { clippedSurrogate, policyLossOf } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const R0 = 0, R1 = centi(K('K_R_HI_C', 200)) +const WIDE = K('K_WIDE', 1000) +const ctl = controls([ + { key: 'r', label: say('SAY_R'), min: R0, max: R1, step: 0.01, fmt: (v) => fmt(v, 2) }, + { key: 'a', label: say('SAY_A'), min: centi(K('K_A_LO_C', -200)), max: centi(K('K_A_HI_C', 200)), step: 0.1, fmt: (v) => fmt(v, 1) }, + { key: 'eps', label: say('SAY_EPS'), min: centi(K('K_EPS_LO_C', 5)), max: centi(K('K_EPS_HI_C', 50)), step: 0.01, fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { r: K('K_PRESET_R_C', []).map(centi), a: K('K_PRESET_A_C', []).map(centi), eps: K('K_PRESET_EPS_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_CLIPPED'), COLORS[0]], [say('SAY_RAW'), COLORS[1], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: R0, x1: R1, y0: K('K_Y_LO', -4), y1: K('K_Y_HI', 4), xticks: K('K_R_TICKS_C', []).map(centi), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_R') } + const p = plot(svg, o) + p.line(sample((r) => clippedSurrogate(r, s.a, WIDE), R0, R1), COLORS[1], 2, { 'stroke-dasharray': '7 6' }) + p.line(sample((r) => clippedSurrogate(r, s.a, s.eps), R0, R1, 400), COLORS[0], 4) + cursor(svg, p, s.r, [[clippedSurrogate(s.r, s.a, s.eps), COLORS[0]], [clippedSurrogate(s.r, s.a, WIDE), COLORS[1]]]) + dragX(svg, p, o, (r) => ctl.set('r', r)) + const rs = K('K_BATCH_R_C', []).map(centi) + stat.replaceChildren(tiles([ + { label: say('SAY_CLIPPED'), value: fmt(clippedSurrogate(s.r, s.a, s.eps), 4), tone: 0 }, + { label: say('SAY_RAW'), value: fmt(clippedSurrogate(s.r, s.a, WIDE), 4), tone: 1 }, + { label: say('SAY_BATCH'), value: fmt(policyLossOf(rs[0], rs[1], rs[2]), 4), tone: 2 }, + { label: say('SAY_BATCH_FAR'), value: fmt(policyLossOf(s.r, s.r, s.r), 4), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-relu/card.png b/apps/website/public/widgets/nn-relu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..8f3f047b7e1fe225a45b3e29cc7cfca3975f4c98 GIT binary patch literal 46904 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 SF2VmmWF!@zeR*Q|`u_pX)r!~v literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-relu/index.html b/apps/website/public/widgets/nn-relu/index.html new file mode 100644 index 0000000000..78fd09b8fe --- /dev/null +++ b/apps/website/public/widgets/nn-relu/index.html @@ -0,0 +1,47 @@ + + + + + + +ReLU: what a neuron does with a negative number · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

ReLU: what a neuron does with a negative number

+

Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/relu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 1 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-relu/logic.js b/apps/website/public/widgets/nn-relu/logic.js new file mode 100644 index 0000000000..2c5e16b7b8 --- /dev/null +++ b/apps/website/public/widgets/nn-relu/logic.js @@ -0,0 +1,32 @@ +// Generated by scripts/t27-logic.mjs from relu_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 0b516ac7e0d25ec67b948833098b21421a1c385cb51abc49146e5855f849f559 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-relu/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABDgJgAAF9YAV9fX19fwF9AwQDAAEBBAUBcAEBAQUDAQARBgkBfwFBgIDAAAsHPwQGbWVtb3J5AgAPdDI3X3ZhbGlkX2lucHV0AAAPdDI3X2JhY2t3YXJkX2F0AAEOdDI3X2ZvcndhcmRfYXQAAgrXAgMHAEMAAADAC6QBAQJ/I4CAgIAAQSBrIgUkgICAgABBACEGIAVBGGpBACgCiIDAgAA2AgAgBSACOAIMIAUgATgCCCAFIAA4AgQgBUEAKQKAgMCAADcDEAJAA0AgBkEMRg0BIAVBEGogBmpDAACAPyADIAVBBGogBmoqAgBDAAAAAF4bOAIAIAZBBGohBgwACwsgBUEQaiAEQQJ0aioCACEDIAVBIGokgICAgAAgAwumAQECfyOAgICAAEEgayIFJICAgIAAQQAhBiAFQRhqQQAoAoiAwIAANgIAIAUgAjgCDCAFIAE4AgggBSAAOAIEIAVBACkCgIDAgAA3AxACQANAIAZBDEYNASAFQRBqIAZqIAVBBGogBmoqAgAiAiADIAKUIAJDAAAAAF4bOAIAIAZBBGohBgwACwsgBUEQaiAEQQJ0aioCACECIAVBIGokgICAgAAgAgsLFQEAQYCAwAALDAAAEEEAABBBAAAQQQ=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forwardAt(a, b, c, slope, index) { + return W.t27_forward_at(a, b, c, slope, int(index, 0, 4294967295, "forward_at.index")); +} +function backwardAt(a, b, c, slope, index) { + return W.t27_backward_at(a, b, c, slope, int(index, 0, 4294967295, "backward_at.index")); +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "cfg"]); +export { + __NOT_LOWERED__, + backwardAt, + forwardAt, + validInput +}; diff --git a/apps/website/public/widgets/nn-relu/logic.t27 b/apps/website/public/widgets/nn-relu/logic.t27 new file mode 100644 index 0000000000..b726401b32 --- /dev/null +++ b/apps/website/public/widgets/nn-relu/logic.t27 @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// ReLU produces sparse gradients | φ² + 1/φ² = 3 | TRINITY + +// #8980: the tests called forward and backward with one or two of their three or +// four arguments, two asserted only `result != undefined`, and the invariants +// asserted `true`. Each test now runs the functions on buffers and checks values. + +module Relu; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const ZERO : f32 = 0.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const ReLUConfig = struct { + negative_slope : f32, + inplace : bool, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // forward(input: []const f32, output: []f32, config: ReLUConfig) → void + fn forward(input: []const f32, output: []f32, config: ReLUConfig) -> void { + // Values at or below ZERO take the negative branch, values above ZERO pass through + // For negative_slope = 0.0, this gives max(0, x) behavior + var i : usize = 0; + while (i < input.len) : (i += 1) { + if (input[i] > ZERO) { + output[i] = input[i]; // Positive branch: identity + } else { + output[i] = input[i] * config.negative_slope; // Negative branch: scaled + } + } + } + + // backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) → void + fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) -> void { + // The gradient gate is on the forward input, not grad_output - this makes gradients sparse + var i : usize = 0; + while (i < input.len) : (i += 1) { + if (input[i] > ZERO) { + grad_input[i] = grad_output[i]; // Positive branch: identity gradient + } else { + grad_input[i] = grad_output[i] * config.negative_slope; // Negative branch: scaled gradient + } + } + } + + // Note: config.inplace is declared but currently unused by these functions. + // The buffers are separate parameters, so the aliasing case is not handled. + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + fn cfg(slope: f32) -> ReLUConfig { + return ReLUConfig{ .negative_slope = slope, .inplace = false }; + } + + // output[index] of forward over (a, b, c) + fn forward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 { + const input : [3]f32 = [a, b, c]; + var output : [3]f32 = [9.0] ** 3; + forward(&input, &output, cfg(slope)); + return output[index]; + } + + // grad_input[index] of backward over (a, b, c), every grad_output 1 + fn backward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 { + const grad_output : [3]f32 = [1.0, 1.0, 1.0]; + const input : [3]f32 = [a, b, c]; + var grad_input : [3]f32 = [9.0] ** 3; + backward(&grad_output, &input, &grad_input, cfg(slope)); + return grad_input[index]; + } + + // The shared fixture: one negative, zero, one positive. + fn valid_input() -> f32 { + return -2.0; + } + + // max(0, x) on (-2, 0, 2) + test "forward_basic_case" + given negative = forward_at(-2.0, 0.0, 2.0, 0.0, 0) + when positive = forward_at(-2.0, 0.0, 2.0, 0.0, 2) + then negative == 0.0 and forward_at(-2.0, 0.0, 2.0, 0.0, 1) == 0.0 and positive == 2.0 + + test "forward_positive_identity" + given slope = 0.0 + when first = forward_at(1.0, 2.0, 3.0, slope, 0) + then first == 1.0 and forward_at(1.0, 2.0, 3.0, slope, 1) == 2.0 and forward_at(1.0, 2.0, 3.0, slope, 2) == 3.0 + + test "forward_negative_scaling" + given slope = 0.5 + when first = forward_at(-1.0, -2.0, -3.0, slope, 0) + then first == -0.5 and forward_at(-1.0, -2.0, -3.0, slope, 1) == -1.0 and forward_at(-1.0, -2.0, -3.0, slope, 2) == -1.5 + + test "forward_zero_negative_slope" + given slope = 0.0 + when first = forward_at(-1.0, 0.0, 1.0, slope, 0) + then first == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 1) == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0 + + // grad_output * negative_slope for input <= ZERO (0 included), grad_output above it + test "backward_input_gate" + given slope = 0.5 + when first = backward_at(-1.0, 0.0, 1.0, slope, 0) + then first == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 1) == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0 + + // Plain ReLU: the gradient is 0 left of zero and passes through right of it + test "backward_basic_case" + given negative = backward_at(-2.0, 0.0, 2.0, 0.0, 0) + when positive = backward_at(-2.0, 0.0, 2.0, 0.0, 2) + then negative == 0.0 and positive == 1.0 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // input.len == output.len: forward writes every element of its buffer (none keeps the 9.0 fill) + invariant relu_constraint_0 + assert forward_at(valid_input(), 0.0, 1.0, 0.0, 0) != 9.0 and forward_at(valid_input(), 0.0, 1.0, 0.0, 2) != 9.0 + + // A finite input gives a finite output: ReLU never exceeds its input's magnitude + invariant relu_constraint_1 + assert @abs(forward_at(valid_input(), 0.0, 1.0, 0.5, 0)) <= @abs(valid_input()) diff --git a/apps/website/public/widgets/nn-relu/nn-relu.t27 b/apps/website/public/widgets/nn-relu/nn-relu.t27 new file mode 100644 index 0000000000..b63bcb47e7 --- /dev/null +++ b/apps/website/public/widgets/nn-relu/nn-relu.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-relu.t27 -- ReLU and leaky ReLU: what a neuron does with a negative number +; Source of truth for public/widgets/nn-relu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-relu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/relu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 1 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 4 and sets a leaky slope from 0 to 0.3. The green +; curve is forward_at over x and the dashed curve backward_at, the slope; the tiles read both at x +; and over the spec's own three-input batch (-2, 0, 2). + +; WHAT IT DOES NOT CLAIM: ReLU is one choice among the activations of module 2; the page measures +; nothing about training. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_relu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-relu"; +pub const TITLE : str = "ReLU: what a neuron does with a negative number"; +pub const DESCRIPTION : str = "Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through."; +pub const IMAGE_ALT : str = "ReLU card: leaky slope 0.1 at x = -2. The green curve is flat at -0.2 on the left and rises at 45 degrees on the right; the dashed gold slope sits at 0.1 then jumps to 1. Tiles read out -0.200, slope 0.100 and the spec's batch (-2, 0, 2) as -0.20 0.00 2.00."; +pub const HOOK : str = "max(0, x) is the whole rule, and its slope is 1 or 0. A leaky slope of 0.1 keeps a gradient alive on the negative side."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/relu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 1 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 400; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -100; +pub const K_Y_HI_C : i16 = 400; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [6]i8 = [-1, 0, 1, 2, 3, 4]; +pub const K_SLOPE_MAX_C : u8 = 30; +pub const K_FIXTURE_C : [3]i16 = [-200, 0, 200]; +pub const K_PRESET_X_C : [4]i16 = [-200, 150, -200, -300]; +pub const K_PRESET_SLOPE_C : [4]u8 = [10, 0, 0, 30]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Leaky 0.1 at x = -2", "ReLU at x = 1.5", "ReLU at x = -2", "Leaky 0.3 at x = -3"]; +pub const SAY_ASK : str = "What does a neuron do with a negative number?"; +pub const SAY_X : str = "input x"; +pub const SAY_SLOPE : str = "leaky slope"; +pub const SAY_F : str = "ReLU(x)"; +pub const SAY_DF : str = "slope dReLU/dx"; +pub const SAY_PLOT_LABEL : str = "ReLU of x and its slope from -4 to 4, with a cursor you drag"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch -2 0 2"; +pub const SAY_BATCH_GRAD : str = "its slopes"; +pub const SAY_NOTE : str = "A slope of 0 means no gradient flows back, so a unit that only ever sees negative inputs stops learning. The leaky slope is the fix the spec takes as its fourth argument."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/relu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_range_holds_both_sides { + assert K_X_LO_C < 0; + assert K_X_HI_C > 0; + assert K_X_LO_C + K_X_HI_C == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_X_C[3] >= K_X_LO_C; + assert K_PRESET_SLOPE_C[3] <= K_SLOPE_MAX_C; + assert K_PRESET_SLOPE_C[1] == 0; + assert K_FIXTURE_C[0] == K_PRESET_X_C[0]; +} diff --git a/apps/website/public/widgets/nn-relu/tool.js b/apps/website/public/widgets/nn-relu/tool.js new file mode 100644 index 0000000000..178ed0cf13 --- /dev/null +++ b/apps/website/public/widgets/nn-relu/tool.js @@ -0,0 +1,38 @@ +// nn-relu/tool.js -- lesson 1 of neural-networks: what a neuron does with a negative number. ReLU +// passes a positive input and zeroes a negative one; a leaky slope lets a little through. It computes +// nothing itself: every point of both curves and every tile is forward_at and backward_at of +// gHashTag/t27 specs/ml/activation/relu_activation.t27, compiled to wasm (./logic.js). Words are SAY_ +// and numbers K_ constants of specs/widgets/nn-relu.t27. +import { backwardAt, forwardAt } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -400)), X1 = centi(K('K_X_HI_C', 400)) +const f = (x, s) => forwardAt(x, 0, 0, s, 0) +const df = (x, s) => backwardAt(x, 0, 0, s, 0) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, + { key: 'slope', label: say('SAY_SLOPE'), min: 0, max: centi(K('K_SLOPE_MAX_C', 30)), step: 0.01, fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi), slope: K('K_PRESET_SLOPE_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_F'), COLORS[0]], [say('SAY_DF'), COLORS[1], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: X0, x1: X1, y0: centi(K('K_Y_LO_C', -100)), y1: centi(K('K_Y_HI_C', 400)), xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_X') } + const p = plot(svg, o) + p.line(sample((x) => f(x, s.slope), X0, X1), COLORS[0], 3) + p.line(sample((x) => df(x, s.slope), X0, X1, 320), COLORS[1], 2, { 'stroke-dasharray': '6 5' }) + cursor(svg, p, s.x, [[f(s.x, s.slope), COLORS[0]], [df(s.x, s.slope), COLORS[1]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + const fx = K('K_FIXTURE_C', []).map(centi) + stat.replaceChildren(tiles([ + { label: say('SAY_OUT'), value: fmt(f(s.x, s.slope), 3), tone: 0 }, + { label: say('SAY_GRAD'), value: fmt(df(s.x, s.slope), 3), tone: 1 }, + { label: say('SAY_BATCH'), value: [0, 1, 2].map((i) => fmt(forwardAt(fx[0], fx[1], fx[2], s.slope, i), 2)).join(' '), tone: 2 }, + { label: say('SAY_BATCH_GRAD'), value: [0, 1, 2].map((i) => fmt(backwardAt(fx[0], fx[1], fx[2], s.slope, i), 2)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-rmsprop/card.png b/apps/website/public/widgets/nn-rmsprop/card.png new file mode 100644 index 0000000000000000000000000000000000000000..d198e0021567223f52ec7d0fe779b78e91c52916 GIT binary patch literal 54199 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 Jvd$@?2>>IA_P+oC literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-rmsprop/index.html b/apps/website/public/widgets/nn-rmsprop/index.html new file mode 100644 index 0000000000..cbcb1194e5 --- /dev/null +++ b/apps/website/public/widgets/nn-rmsprop/index.html @@ -0,0 +1,47 @@ + + + + + + +RMSProp: a step that does not care how big the gradient is · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +

+Trinity S³AI +

RMSProp: a step that does not care how big the gradient is

+

Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/optimizer/rmsprop.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 17 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-rmsprop/logic.js b/apps/website/public/widgets/nn-rmsprop/logic.js new file mode 100644 index 0000000000..6b4d240fb5 --- /dev/null +++ b/apps/website/public/widgets/nn-rmsprop/logic.js @@ -0,0 +1,28 @@ +// Generated by scripts/t27-logic.mjs from rmsprop.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: f483ccb6c0ffa9f2b941a64d00daae8d69823fb982fd2f2b1a9fca9638c44ab7 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-rmsprop/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABDgJgAn1/AX1gA31/fQF9AwMCAAEEBQFwAQEBBQMBABAGCQF/AUGAgMAACwcuAwZtZW1vcnkCAA90MjdfY2FjaGVfYWZ0ZXIAAA90MjdfcGFyYW1fYWZ0ZXIAAQqZAQI7AQF9IAAgAEPQzMw9lJQhAkMAAAAAIQACQANAIAFFDQEgAUF/aiEBIAIgAENmZmY/lJIhAAwACwsgAAtbAQN9IABDCtcjPJQhA0MAAIA/IQQgACAAQwAAgD8gApOUlCEFQwAAAAAhAAJAA0AgAUUNASABQX9qIQEgBCADIAUgAiAAlJIiAJFDd8wrMpKVkyEEDAALCyAECw=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function paramAfter(g, steps, decay) { + return W.t27_param_after(g, int(steps, 0, 4294967295, "param_after.steps"), decay); +} +function cacheAfter(g, steps) { + return W.t27_cache_after(g, int(steps, 0, 4294967295, "cache_after.steps")); +} +const __NOT_LOWERED__ = Object.freeze(["step"]); +export { + __NOT_LOWERED__, + cacheAfter, + paramAfter +}; diff --git a/apps/website/public/widgets/nn-rmsprop/logic.t27 b/apps/website/public/widgets/nn-rmsprop/logic.t27 new file mode 100644 index 0000000000..ab0e105933 --- /dev/null +++ b/apps/website/public/widgets/nn-rmsprop/logic.t27 @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// RMSprop optimizer with moving average of squared gradients | φ² + 1/φ² = 3 | TRINITY +// Restored 2026-10-05 from trinity specs/algo/rmsprop.tri. The port kept only +// `grad`, squared grad[0], and threw it away; the test read an undefined +// default_input(). + +module Rmsprop; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_DECAY : f32 = 0.9; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const RMSpropConfig = struct { + learning_rate : f32, + decay : f32, + epsilon : f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // step(grad, param, cache, config) -> void, in place: + // cache = decay * cache + (1 - decay) * grad^2 + // param -= lr * grad / (sqrt(cache) + epsilon) + // The .tri formula reads lr, decay and epsilon but its parameter list + // omits them; they come from config here. + fn step(grad: []const f32, param: []f32, cache: []f32, config: RMSpropConfig) -> void { + var i : usize = 0; + while (i < grad.len) { + const g = grad[i]; + cache[i] = config.decay * cache[i] + (1.0 - config.decay) * g * g; + param[i] = param[i] - config.learning_rate * g / (@sqrt(cache[i]) + config.epsilon); + i = i + 1; + } + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests + // ═══════════════════════════════════════════════════════════ + + // run `steps` steps of constant gradient g on one parameter from 1.0 + fn param_after(g: f32, steps: usize, decay: f32) -> f32 { + const grad : [1]f32 = [g]; + var param : [1]f32 = [1.0]; + var cache : [1]f32 = [0.0]; + var k : usize = 0; + while (k < steps) { + step(&grad, ¶m, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = decay, .epsilon = 0.00000001 }); + k = k + 1; + } + return param[0]; + } + + fn cache_after(g: f32, steps: usize) -> f32 { + const grad : [1]f32 = [g]; + var param : [1]f32 = [1.0]; + var cache : [1]f32 = [0.0]; + var k : usize = 0; + while (k < steps) { + step(&grad, ¶m, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = DEFAULT_DECAY, .epsilon = 0.00000001 }); + k = k + 1; + } + return cache[0]; + } + + // first step from cache 0: cache = 0.1 g^2, so the move is lr / sqrt(0.1) + // = 0.0316228 whatever the size of g + test first_step_is_scale_free + given small = param_after(0.001, 1, DEFAULT_DECAY) + when large = param_after(1000.0, 1, DEFAULT_DECAY) + then @abs(small - (1.0 - 0.0316228)) < 0.00001 and @abs(large - small) < 0.00001 + + // moving average of a constant: cache_n = (1 - 0.9^n) g^2 + test cache_is_moving_average + given result = cache_after(2.0, 3) + when expected = (1.0 - 0.729) * 4.0 + then @abs(result - expected) < 0.00001 + + test moves_against_the_gradient + given up = param_after(0.5, 2, DEFAULT_DECAY) + when down = param_after(-0.5, 2, DEFAULT_DECAY) + then up < 1.0 and down > 1.0 and @abs((1.0 - up) - (down - 1.0)) < 0.00001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants + // ═══════════════════════════════════════════════════════════ + + invariant rmsprop_decay_in_unit_interval + assert DEFAULT_DECAY > 0.0 and DEFAULT_DECAY < 1.0 diff --git a/apps/website/public/widgets/nn-rmsprop/nn-rmsprop.t27 b/apps/website/public/widgets/nn-rmsprop/nn-rmsprop.t27 new file mode 100644 index 0000000000..1ee610febf --- /dev/null +++ b/apps/website/public/widgets/nn-rmsprop/nn-rmsprop.t27 @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-rmsprop.t27 -- RMSProp: a step that ignores the size of the gradient +; Source of truth for public/widgets/nn-rmsprop/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-rmsprop/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/rmsprop.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 17 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks a gradient, a decay from 0.5 to 0.99 and a number of steps. Every +; point is param_after(g, n, decay) from 1.0 with lr 0.01, the cache cache_after(g, n) at the spec's +; decay 0.9. + +; WHAT IT DOES NOT CLAIM: a constant gradient on one weight; with a changing gradient the cache lags +; behind it. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_rmsprop; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-rmsprop"; +pub const TITLE : str = "RMSProp: a step that does not care how big the gradient is"; +pub const DESCRIPTION : str = "Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends."; +pub const IMAGE_ALT : str = "RMSProp card: gradient 0.5, decay 0.9, 100 steps. Three lines, green for 0.5 and dashed gold and pink for 0.001 and 1000, lie exactly on top of each other, falling from 1 to about -0.09. Tiles read the weight -0.09142, the three runs -0.0914 -0.0914 -0.0914, one step 0.96838 and the cache 0.249993."; +pub const HOOK : str = "Its first step is 0.0316 whether the gradient is 0.001 or 1000. Dividing by the gradient's own size is what makes the step scale-free."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/rmsprop.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 17 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 100; +pub const K_GRADS_M : [3]u32 = [1, 500, 1000000]; +pub const K_DECAY_LO_C : u8 = 50; +pub const K_DECAY_HI_C : u8 = 99; +pub const K_Y_LO_C : i16 = -110; +pub const K_Y_HI_C : u8 = 110; +pub const K_Y_TICKS_C : [5]i8 = [-100, -50, 0, 50, 100]; +pub const K_STEP_TICKS : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_G : [4]u8 = [1, 0, 2, 1]; +pub const K_PRESET_DECAY_C : [4]u8 = [90, 90, 90, 99]; +pub const K_PRESET_STEPS : [4]u8 = [100, 100, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["g = 0.5", "g = 0.001", "g = 1000", "g = 0.5, decay 0.99"]; +pub const SAY_ASK : str = "Can a step ignore how big the gradient is?"; +pub const SAY_GRAD : str = "gradient"; +pub const SAY_GRAD_NAMES : [3]str = ["g = 0.001", "g = 0.5", "g = 1000"]; +pub const SAY_DECAY : str = "decay"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_PLOT_LABEL : str = "The weight after every step for three gradient sizes"; +pub const SAY_W_NOW : str = "weight now"; +pub const SAY_W_OTHERS : str = "all three gradients"; +pub const SAY_ONE_STEP : str = "after step 1"; +pub const SAY_CACHE : str = "cache, decay 0.9"; +pub const SAY_NOTE : str = "The cache is a running mean of g squared, so g / sqrt(cache) has no units: a layer whose gradients are tiny moves as fast as one whose gradients are huge."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/rmsprop.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_gradients_span_six_decades { + assert K_GRADS_M[0] == 1; + assert K_GRADS_M[2] == 1000000; + assert K_GRADS_M[1] == 500; +} + +test the_presets_stay_in_range { + assert K_PRESET_G[2] < 3; + assert K_PRESET_DECAY_C[3] == K_DECAY_HI_C; + assert K_PRESET_STEPS[0] == K_STEPS_HI; +} diff --git a/apps/website/public/widgets/nn-rmsprop/tool.js b/apps/website/public/widgets/nn-rmsprop/tool.js new file mode 100644 index 0000000000..6fb4803561 --- /dev/null +++ b/apps/website/public/widgets/nn-rmsprop/tool.js @@ -0,0 +1,37 @@ +// nn-rmsprop/tool.js -- lesson 17 of neural-networks: a step that does not care how big the gradient +// is. RMSProp divides each step by the root of a running mean of squared gradients, so a gradient +// of 0.001 and one of 1000 move the weight alike. Every point is param_after and every cache value +// cache_after of gHashTag/t27 specs/ml/optimizer/rmsprop.t27, compiled to wasm (./logic.js): a +// constant gradient on one weight from 1.0, lr 0.01. Words are SAY_ and numbers K_ constants of +// specs/widgets/nn-rmsprop.t27. +import { cacheAfter, paramAfter } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, say, source, tiles } from '../nn-kit.js' + +const NMAX = K('K_STEPS_HI', 100) +const G = K('K_GRADS_M', []).map((g) => g / 1000) +const ctl = controls([ + { key: 'g', label: say('SAY_GRAD'), kind: 'choice', options: W.SAY_GRAD_NAMES ?? [] }, + { key: 'decay', label: say('SAY_DECAY'), min: centi(K('K_DECAY_LO_C', 50)), max: centi(K('K_DECAY_HI_C', 99)), step: 0.01, fmt: (v) => fmt(v, 2) }, + { key: 'n', label: say('SAY_STEPS'), min: 1, max: NMAX }, +], { names: W.SAY_PRESET_NAMES, values: { g: K('K_PRESET_G', []), decay: K('K_PRESET_DECAY_C', []).map(centi), n: K('K_PRESET_STEPS', []) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend((W.SAY_GRAD_NAMES ?? []).map((w, i) => [w, COLORS[[0, 1, 3][i]], i > 0])), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 330, x0: 0, x1: NMAX, y0: centi(K('K_Y_LO_C', -10)), y1: centi(K('K_Y_HI_C', 110)), xticks: K('K_STEP_TICKS', []), yticks: K('K_Y_TICKS_C', []).map(centi), xlabel: say('SAY_STEPS') } + const p = plot(svg, o) + G.forEach((g, i) => p.line([...Array(NMAX + 1)].map((_, k) => [k, paramAfter(g, k, s.decay)]), COLORS[[0, 1, 3][i]], i === s.g ? 5 : 2, i === s.g ? {} : { 'stroke-dasharray': '6 6' })) + cursor(svg, p, s.n, [[paramAfter(G[s.g], s.n, s.decay), COLORS[[0, 1, 3][s.g]]]]) + dragX(svg, p, o, (n) => ctl.set('n', Math.round(n))) + stat.replaceChildren(tiles([ + { label: say('SAY_W_NOW'), value: fmt(paramAfter(G[s.g], s.n, s.decay), 5), tone: 0 }, + { label: say('SAY_W_OTHERS'), value: G.map((g) => fmt(paramAfter(g, s.n, s.decay), 4)).join(' '), tone: 1 }, + { label: say('SAY_ONE_STEP'), value: fmt(paramAfter(G[s.g], 1, s.decay), 5), tone: 2 }, + { label: say('SAY_CACHE'), value: fmt(cacheAfter(G[s.g], s.n), 6), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-rnn/card.png b/apps/website/public/widgets/nn-rnn/card.png new file mode 100644 index 0000000000000000000000000000000000000000..b61326514d806cbc4452d77007c706e89071c110 GIT binary patch literal 38490 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-rnn/index.html b/apps/website/public/widgets/nn-rnn/index.html new file mode 100644 index 0000000000..7260d8bcf0 --- /dev/null +++ b/apps/website/public/widgets/nn-rnn/index.html @@ -0,0 +1,47 @@ + + + + + + +Recurrent cells: how a network remembers a moment ago · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Recurrent cells: how a network remembers a moment ago

+

Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/recurrent/rnn_cell.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 22 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-rnn/logic.js b/apps/website/public/widgets/nn-rnn/logic.js new file mode 100644 index 0000000000..98f888ea96 --- /dev/null +++ b/apps/website/public/widgets/nn-rnn/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from rnn_cell.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 09f67415a49b61d028c7a15e93caff8f3d3d309b7bb9452b1b6260132caf8887 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-rnn/: types stripped, nothing else changed. +const WASM = "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"; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function tinyStep(x, h) { + return W.t27_tiny_step(x, h); +} +function tinySequence(t) { + return W.t27_tiny_sequence(int(t, 0, 4294967295, "tiny_sequence.t")); +} +function wideStep(index) { + return W.t27_wide_step(int(index, 0, 4294967295, "wide_step.index")); +} +function initLen(hiddenSize) { + return W.t27_init_len(int(hiddenSize, 0, 4294967295, "init_len.hidden_size")) >>> 0; +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["forward_step", "forward_sequence", "init_state", "tiny"]); +export { + __NOT_LOWERED__, + initLen, + tinySequence, + tinyStep, + validInput, + wideStep +}; diff --git a/apps/website/public/widgets/nn-rnn/logic.t27 b/apps/website/public/widgets/nn-rnn/logic.t27 new file mode 100644 index 0000000000..0ad0f92fae --- /dev/null +++ b/apps/website/public/widgets/nn-rnn/logic.t27 @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Basic RNN recurrence equation | φ² + 1/φ² = 3 | TRINITY + +// #8980: written against undeclared `matmul`, `add`, `zeros`, `len` and `append`, +// it applied tanh twice (h = tanh(tanh(z))), and the tests asserted +// `result != undefined`. It is now the Elman cell, +// h' = tanh(W_x x + W_h h + b), with W_x hidden x input and W_h hidden x hidden +// (row-major), stepping over buffers the caller owns. + +module RnnCell; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_INPUT_SIZE : u32 = 128; + const DEFAULT_HIDDEN_SIZE : u32 = 128; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const RNNCellConfig = struct { + input_size : u32, + hidden_size : u32, + }; + + pub const RNNState = struct { + hidden : []f32, + cell : []f32, + }; + + pub const RNNParams = struct { + w_x : []f32, + w_h : []f32, + b : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // new_hidden[i] = tanh(sum_j W_x[i][j] x[j] + sum_k W_h[i][k] h[k] + b[i]) + fn forward_step(input: []const f32, hidden: []const f32, params: RNNParams, config: RNNCellConfig, new_hidden: []f32) -> void { + var i : usize = 0; + while (i < config.hidden_size) { + var z : f32 = params.b[i]; + var j : usize = 0; + while (j < config.input_size) { + z = z + params.w_x[i * config.input_size + j] * input[j]; + j = j + 1; + } + var k : usize = 0; + while (k < config.hidden_size) { + z = z + params.w_h[i * config.hidden_size + k] * hidden[k]; + k = k + 1; + } + new_hidden[i] = tanh(z); + i = i + 1; + } + } + + // inputs: steps x input_size; outputs: steps x hidden_size, row t = h after step t. + // The state starts at initial_state and each step reads the previous row. + fn forward_sequence(inputs: []const f32, steps: usize, initial_state: []const f32, params: RNNParams, config: RNNCellConfig, outputs: []f32) -> void { + const n_in : usize = config.input_size; + const n_h : usize = config.hidden_size; + var t : usize = 0; + while (t < steps) { + if (t == 0) { + forward_step(inputs[0..n_in], initial_state, params, config, outputs[0..n_h]); + } else { + forward_step(inputs[t * n_in .. (t + 1) * n_in], outputs[(t - 1) * n_h .. t * n_h], params, config, outputs[t * n_h .. (t + 1) * n_h]); + } + t = t + 1; + } + } + + // The first hidden_size entries of `buffer`, zeroed + fn init_state(buffer: []f32, hidden_size: u32) -> []f32 { + var i : usize = 0; + while (i < hidden_size) { + buffer[i] = 0.0; + i = i + 1; + } + return buffer[0..hidden_size]; + } + + // A 1-in, 1-hidden cell with W_x = 1, W_h = 0.5, b = 0: h' = tanh(x + 0.5 h) + fn tiny() -> RNNCellConfig { + return RNNCellConfig{ .input_size = 1, .hidden_size = 1 }; + } + + fn tiny_step(x: f32, h: f32) -> f32 { + var w_x : [1]f32 = [1.0]; + var w_h : [1]f32 = [0.5]; + var b : [1]f32 = [0.0]; + const input : [1]f32 = [x]; + const hidden : [1]f32 = [h]; + var out : [1]f32 = [9.0]; + forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &out); + return out[0]; + } + + // The sequence (1, 0, 0) from h = 0: h after step t + fn tiny_sequence(t: usize) -> f32 { + var w_x : [1]f32 = [1.0]; + var w_h : [1]f32 = [0.5]; + var b : [1]f32 = [0.0]; + const inputs : [3]f32 = [1.0, 0.0, 0.0]; + const h0 : [1]f32 = [0.0]; + var outputs : [3]f32 = [9.0] ** 3; + forward_sequence(&inputs, 3, &h0, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &outputs); + return outputs[t]; + } + + // A 2-in, 2-hidden cell: h' = tanh(W_x x + W_h h + b) with W_x = [[1, -1], [0.5, 0.5]], + // W_h = [[0.1, 0], [0, 0.1]], b = (0, -0.5), at x = (1, 2), h = (1, -1) + fn wide_step(index: usize) -> f32 { + var w_x : [4]f32 = [1.0, -1.0, 0.5, 0.5]; + var w_h : [4]f32 = [0.1, 0.0, 0.0, 0.1]; + var b : [2]f32 = [0.0, -0.5]; + const input : [2]f32 = [1.0, 2.0]; + const hidden : [2]f32 = [1.0, -1.0]; + var out : [2]f32 = [9.0] ** 2; + forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, RNNCellConfig{ .input_size = 2, .hidden_size = 2 }, &out); + return out[index]; + } + + fn init_len(hidden_size: u32) -> usize { + var buffer : [64]f32 = [9.0] ** 64; + const h = init_state(&buffer, hidden_size); + if (h[hidden_size - 1] != 0.0) { + return 0; + } + return h.len; + } + + fn valid_input() -> f32 { + return tiny_step(1.0, 0.0); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // z = (1 - 2 + 0.1, 0.5 + 1 - 0.1 - 0.5) = (-0.9, 0.9): h' = (tanh(-0.9), tanh(0.9)) + test forward_step_basic_case + given h0 = wide_step(0) + when h1 = wide_step(1) + then @abs(h0 + 0.7162979) < 0.000001 and @abs(h1 - 0.7162979) < 0.000001 and @abs(tiny_step(1.0, 0.0) - 0.7615942) < 0.000001 + + // The cell remembers: after the input pulse, h decays through the recurrent weight, + // h1 = tanh(1), h2 = tanh(0.5 h1), h3 = tanh(0.5 h2) + test forward_sequence_basic_case + given h1 = tiny_sequence(0) + when h3 = tiny_sequence(2) + then @abs(h1 - 0.7615942) < 0.000001 and @abs(tiny_sequence(1) - tanh(0.5 * h1)) < 0.000001 and @abs(h3 - tanh(0.5 * tiny_sequence(1))) < 0.000001 and h3 > 0.0 and h3 < tiny_sequence(1) + + test init_state_basic_case + given hidden_size = 64 + when result = init_len(hidden_size) + then result == hidden_size + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // input_size >= 1 + invariant rnn_cell_constraint_0 + assert DEFAULT_INPUT_SIZE >= 1 + + // hidden_size >= 1 + invariant rnn_cell_constraint_1 + assert DEFAULT_HIDDEN_SIZE >= 1 + + // name: rnn_formula -- one tanh, not two: tanh(1) = 0.7615942, tanh(tanh(1)) = 0.6420 + invariant rnn_cell_constraint_2 + assert valid_input() > 0.76 and valid_input() < 0.77 + + // "Elman (1990) - Finding Structure in Time": the state carries the past forward + invariant rnn_cell_constraint_3 + assert tiny_step(0.0, 1.0) > 0.0 + + // "Goodfellow et al. (2016) - Sequence Modeling with RNNs and LSTMs": tanh bounds the state + invariant rnn_cell_constraint_4 + assert tiny_step(100.0, 1.0) <= 1.0 and tiny_step(-100.0, -1.0) >= -1.0 diff --git a/apps/website/public/widgets/nn-rnn/nn-rnn.t27 b/apps/website/public/widgets/nn-rnn/nn-rnn.t27 new file mode 100644 index 0000000000..2335230222 --- /dev/null +++ b/apps/website/public/widgets/nn-rnn/nn-rnn.t27 @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-rnn.t27 -- a recurrent cell: an echo that fades +; Source of truth for public/widgets/nn-rnn/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-rnn/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/rnn_cell.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 22 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader taps each of eight inputs to cycle it through -1, 0 and +1. Each h is +; tiny_step(x, h) of the spec, applied in order from h = 0; the spec's own three-step run is +; tiny_sequence(t). + +; WHAT IT DOES NOT CLAIM: a 1-in, 1-hidden cell with the spec's weights (W_x 1, W_h 0.5, b 0); a +; real cell has a vector of hidden units. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_rnn; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-rnn"; +pub const TITLE : str = "Recurrent cells: how a network remembers a moment ago"; +pub const DESCRIPTION : str = "Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up."; +pub const IMAGE_ALT : str = "RNN card: inputs +1, 0, 0, +1, 0, 0, 0, 0 as cyan bars, and the green hidden state jumping to 0.76, fading to 0.36 and 0.18, jumping to 0.80 at the second pulse and fading to 0.05. Tiles read the last h 0.0466 and the spec's own run 0.7616 0.3634 0.1797."; +pub const HOOK : str = "A single pulse gives 0.762, 0.363, 0.180: the memory halves each step. A cell remembers, but not for long, which is the problem LSTMs solve."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/rnn_cell.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 22 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS : u8 = 8; +pub const K_Y_TICKS : [3]i8 = [-1, 0, 1]; +pub const K_PRESET_INPUTS : [32]i8 = [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Two pulses", "One pulse", "Alternating", "Always on"]; +pub const SAY_ASK : str = "How does a network remember what it saw a moment ago?"; +pub const SAY_TAP : str = "Inputs: tap a step to change it"; +pub const SAY_STEP : str = "step"; +pub const SAY_X : str = "input x"; +pub const SAY_H : str = "hidden state h"; +pub const SAY_PLOT_LABEL : str = "Input and hidden state at every step"; +pub const SAY_H_LAST : str = "h, last step"; +pub const SAY_H_ALL : str = "h at every step"; +pub const SAY_SPEC_RUN : str = "spec run 1, 0, 0"; +pub const SAY_ECHO : str = "echo of one pulse"; +pub const SAY_NOTE : str = "The same weights act at every step, and the state h carries what came before. Because 0.5 h is squeezed by tanh each time, an old input fades geometrically."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/rnn_cell.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test eight_steps_four_presets { + assert K_STEPS == 8; + assert K_PRESET_INPUTS[0] == 1; + assert K_PRESET_INPUTS[3] == 1; +} + +test the_inputs_are_trits { + assert K_PRESET_INPUTS[17] + 1 == 0; + assert K_PRESET_INPUTS[31] == 1; + assert K_PRESET_INPUTS[8] == 1; + assert K_PRESET_INPUTS[9] == 0; +} diff --git a/apps/website/public/widgets/nn-rnn/tool.js b/apps/website/public/widgets/nn-rnn/tool.js new file mode 100644 index 0000000000..7a7b152671 --- /dev/null +++ b/apps/website/public/widgets/nn-rnn/tool.js @@ -0,0 +1,44 @@ +// nn-rnn/tool.js -- lesson 22 of neural-networks: how a network remembers what it saw a moment ago. +// A recurrent cell feeds its own last output back in: h' = tanh(x + 0.5 h), so a pulse echoes on and +// fades by about half each step. Every h is tiny_step of gHashTag/t27 specs/ml/recurrent/ +// rnn_cell.t27, compiled to wasm (./logic.js), applied once per input in order; the spec's own +// three-step run is tiny_sequence. Tap a step to change its input. Words are SAY_ and numbers K_ +// constants of specs/widgets/nn-rnn.t27. +import { tinySequence, tinyStep } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, el, fmt, legend, plot, root, say, source, svgEl, tiles } from '../nn-kit.js' + +const N = K('K_STEPS', 8) +const keys = [...Array(N)].map((_, t) => `x${t}`) +const presets = K('K_PRESET_INPUTS', []) +const ctl = controls(keys.map((key) => ({ key, kind: 'hidden', min: -1, max: 1 })), + { names: W.SAY_PRESET_NAMES, values: Object.fromEntries(keys.map((k, t) => [k, (W.SAY_PRESET_NAMES ?? []).map((_, p) => presets[p * N + t])])) }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const row = el('div', { class: 'nn-steps', role: 'group', 'aria-label': say('SAY_TAP') }) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('p', { class: 'dk-label' }, say('SAY_TAP')), row, svg, legend([[say('SAY_X'), COLORS[2]], [say('SAY_H'), COLORS[0]]]), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const xs = keys.map((k) => s[k]) + const hs = [] + let h = 0 + for (const x of xs) hs.push((h = tinyStep(x, h))) + row.replaceChildren(...xs.map((x, t) => { + const b = el('button', { class: 't27-btn', type: 'button', 'aria-label': `${say('SAY_STEP')} ${t}` }, x > 0 ? '+1' : x < 0 ? '−1' : '0') + b.addEventListener('click', () => ctl.set(keys[t], x >= 1 ? -1 : x + 1)) + return b + })) + svg.replaceChildren() + const p = plot(svg, { w: 640, h: 320, x0: -0.5, x1: N - 0.5, y0: -1.1, y1: 1.1, xticks: [...Array(N)].map((_, t) => t), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_STEP') }) + xs.forEach((x, t) => svg.append(svgEl('rect', { x: p.x(t) - 14, y: Math.min(p.y(0), p.y(x)), width: 28, height: Math.max(2, Math.abs(p.y(x) - p.y(0))), rx: 5, fill: COLORS[2], opacity: 0.55 }))) + p.line(hs.map((v, t) => [t, v]), COLORS[0], 3) + hs.forEach((v, t) => svg.append(svgEl('circle', { cx: p.x(t), cy: p.y(v), r: 6, fill: COLORS[0], stroke: '#020403', 'stroke-width': 2 }))) + stat.replaceChildren(tiles([ + { label: say('SAY_H_LAST'), value: fmt(hs[N - 1], 4), tone: 0 }, + { label: say('SAY_H_ALL'), value: hs.map((v) => fmt(v, 2)).join(' '), tone: 1 }, + { label: say('SAY_SPEC_RUN'), value: [0, 1, 2].map((t) => fmt(tinySequence(t), 4)).join(' '), tone: 2 }, + { label: say('SAY_ECHO'), value: [tinyStep(1, 0), tinyStep(0, tinyStep(1, 0))].map((v) => fmt(v, 4)).join(' '), tone: 5 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-sgd/card.png b/apps/website/public/widgets/nn-sgd/card.png new file mode 100644 index 0000000000000000000000000000000000000000..2f28ed03bbabfbd5c28de29e10169db12080f36a GIT binary patch literal 51813 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 vHm`#NL7z)+;P=am`MZTg;E(sOs0 + + + + + +Gradient descent: how a network walks downhill · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Gradient descent: how a network walks downhill

+

Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/optimizer/sgd.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 16 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-sgd/logic.js b/apps/website/public/widgets/nn-sgd/logic.js new file mode 100644 index 0000000000..be989dea83 --- /dev/null +++ b/apps/website/public/widgets/nn-sgd/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from sgd.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: d344b6438e73f6e275f3837c14267919d3629fa0e12898a96451e2782885884f +// Imported by scripts/widget-logic.mjs for public/widgets/nn-sgd/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABHwVgAAF9YAV/f39/fwBgAX8BfWACf38AYAR9fX9/AX0DCAcAAAECAgMEBAUBcAEBAQUDAQARBgkBfwFBgIDAAAsHXAYGbWVtb3J5AgAPdDI3X3ZhbGlkX2lucHV0AAAOdDI3X2RlY2F5X3N0ZXAAAQx0Mjdfb25lX3N0ZXAAAw90MjdfaW5pdF96ZXJvZXMABAt0MjdfZGVzY2VuZAAGCuAGBwcAQwrXIzwLjwECAX8BfSOAgICAAEEwayIAJICAgIAAIABBATYCFCAAQQA2AgwgAEGAgICABDYCCCAAQoCAgPgDNwIgIABCzZmz7gM3AhggAEEAOgAoIAAgAEEMajYCECAAQQA6ACwgAEEIakEBQYCAwIAAIABBEGogAEEYahCCgICAACAAKgIIIQEgAEEwaiSAgICAACABC70BAQZ9QwAAgD8gBCoCDJMhBSAEKgIIIQYgBCoCBCEHIAQqAgAhCCADKAIAIQMgBC0AEEEBcSEEA0ACQAJAIAFFDQAgAioCACAGIAAqAgCUkiEJIAdDAAAAAF5FDQEgAyAFIAmUIAcgAyoCAJSSIgo4AgACQCAEDQAgCiEJDAILIAkgByAKlJIhCQwBCw8LIAAgACoCACAIIAmUkzgCACADQQRqIQMgAEEEaiEAIAJBBGohAiABQX9qIQEMAAsLmwECAX8BfSOAgICAAEEwayIBJICAgIAAIAFBAjYCFCABQgA3AgggAUKAgID8g4CAgMAANwIAIAFC76SM1AM3AiAgAUKKro/h48yZsz83AhggAUEAOgAoIAEgAUEIajYCECABQQA6ACwgAUECQYSAwIAAIAFBEGogAUEYahCCgICAACABIABBAnRqKgIAIQIgAUEwaiSAgICAACACC20CAX8BfSOAgICAAEEgayIBJICAgIAAIAFBAzYCHCABQYCAgIcENgIUIAFCgICAh4SAgPDAADcCDCABIAFBDGo2AhggAUEYakEDEIWAgIAAIAFBDGogAEECdGoqAgAhAiABQSBqJICAgIAAIAILKwAgACgCACEAAkADQCABRQ0BIABBADYCACAAQQRqIQAgAUF/aiEBDAALCwvOAQIBfwF9I4CAgIAAQTBrIgQkgICAgAAgBEEBNgIQIARBgICAhQQ2AgggBEEANgIEIAQgBEEIajYCDCAEQQxqQQEQhYCAgABDAAAAACEFIAJBAXEhAgJAA0AgA0UNASAEIAVDAABAwJIiBSAFkjgCFCAEQgA3AiAgBCABOAIcIAQgADgCGCAEIAI6ACggBCACOgAsIARBBGpBASAEQRRqIARBDGogBEEYahCCgICAACADQX9qIQMgBCoCBCEFDAALCyAEQTBqJICAgIAAIAULCxUBAEGAgMAACwwAAAAAzczMPc3MTD4="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function descend(lr, momentum, nesterov, steps) { + return W.t27_descend(lr, momentum, nesterov ? 1 : 0, int(steps, 0, 4294967295, "descend.steps")); +} +function initZeroes(index) { + return W.t27_init_zeroes(int(index, 0, 4294967295, "init_zeroes.index")); +} +function oneStep(index) { + return W.t27_one_step(int(index, 0, 4294967295, "one_step.index")); +} +function decayStep() { + return W.t27_decay_step(); +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["init", "update", "cfg"]); +export { + __NOT_LOWERED__, + decayStep, + descend, + initZeroes, + oneStep, + validInput +}; diff --git a/apps/website/public/widgets/nn-sgd/logic.t27 b/apps/website/public/widgets/nn-sgd/logic.t27 new file mode 100644 index 0000000000..af7c998fa1 --- /dev/null +++ b/apps/website/public/widgets/nn-sgd/logic.t27 @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Nesterov accelerated gradient (NAG) | φ² + 1/φ² = 3 | TRINITY + +// #8980: init called `new f32[n]`; update read undeclared locals; dampening and +// nesterov were ignored; and weight decay was ADDED to the parameter +// (`- v + wd * p`), which grows the weights it should shrink. update is now +// PyTorch's SGD: g = grad + wd p; v = mu v + (1 - dampening) g; +// step = g + mu v (Nesterov) or v; p = p - lr step. + +module Sgd; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_LR : f32 = 0.01; + const DEFAULT_MOMENTUM : f32 = 0.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const SGDConfig = struct { + learning_rate : f32, + momentum : f32, + weight_decay : f32, + dampening : f32, + nesterov : bool, + }; + + pub const SGDState = struct { + velocity : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // init: the first param_count velocities start at zero (the caller owns the buffer) + fn init(state: SGDState, param_count: u32) -> void { + var i : usize = 0; + while (i < param_count) { + state.velocity[i] = 0.0; + i = i + 1; + } + } + + fn update(params: []f32, grads: []const f32, state: SGDState, config: SGDConfig) -> void { + var i : usize = 0; + while (i < params.len) { + const g = grads[i] + config.weight_decay * params[i]; + var step = g; + if (config.momentum > 0.0) { + state.velocity[i] = config.momentum * state.velocity[i] + (1.0 - config.dampening) * g; + if (config.nesterov) { + step = g + config.momentum * state.velocity[i]; + } else { + step = state.velocity[i]; + } + } + params[i] = params[i] - config.learning_rate * step; + i = i + 1; + } + } + + fn cfg(lr: f32, momentum: f32, wd: f32, nesterov: bool) -> SGDConfig { + return SGDConfig{ .learning_rate = lr, .momentum = momentum, .weight_decay = wd, .dampening = 0.0, .nesterov = nesterov }; + } + + // Minimise f(x) = (x - 3)^2 (gradient 2 (x - 3)) from x = 0 for `steps` steps + fn descend(lr: f32, momentum: f32, nesterov: bool, steps: u32) -> f32 { + var params : [1]f32 = [0.0]; + var velocity : [1]f32 = [5.0]; + const state = SGDState{ .velocity = &velocity }; + init(state, 1); + var n : u32 = 0; + while (n < steps) { + const grads : [1]f32 = [2.0 * (params[0] - 3.0)]; + update(¶ms, &grads, state, cfg(lr, momentum, 0.0, nesterov)); + n = n + 1; + } + return params[0]; + } + + fn init_zeroes(index: usize) -> f32 { + var velocity : [3]f32 = [7.0, 7.0, 7.0]; + init(SGDState{ .velocity = &velocity }, 3); + return velocity[index]; + } + + // One step on params (1, 2), grads (0.1, 0.2), momentum 0.9, weight decay 0.001 + fn one_step(index: usize) -> f32 { + var params : [2]f32 = [1.0, 2.0]; + const grads : [2]f32 = [0.1, 0.2]; + var velocity : [2]f32 = [0.0, 0.0]; + update(¶ms, &grads, SGDState{ .velocity = &velocity }, cfg(0.01, 0.9, 0.001, false)); + return params[index]; + } + + // A step with zero gradient and weight decay shrinks the weight toward 0 + fn decay_step() -> f32 { + var params : [1]f32 = [2.0]; + const grads : [1]f32 = [0.0]; + var velocity : [1]f32 = [0.0]; + update(¶ms, &grads, SGDState{ .velocity = &velocity }, cfg(0.1, 0.0, 0.5, false)); + return params[0]; + } + + fn valid_input() -> f32 { + return DEFAULT_LR; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test "init_basic_case" + given first = init_zeroes(0) + when last = init_zeroes(2) + then first == 0.0 and last == 0.0 + + // v = g + wd p (momentum starts at 0): p0 = 1 - 0.01 (0.1 + 0.001) = 0.99899 + test "update_basic_case" + given p0 = one_step(0) + when p1 = one_step(1) + then p0 != 1.0 and p1 != 2.0 and @abs(p0 - 0.99899) < 0.000001 and @abs(p1 - (2.0 - 0.01 * 0.202)) < 0.000001 + + // Weight decay pulls the weight toward 0: 2 - 0.1 * 0.5 * 2 = 1.9 + test "update_weight_decay_shrinks" + given result = decay_step() + then @abs(result - 1.9) < 0.000001 + + // Plain, momentum and Nesterov SGD all reach the minimum at 3 + test "update_descends_a_quadratic" + given plain = descend(0.1, 0.0, false, 100) + when heavy = descend(0.05, 0.9, false, 300) + then @abs(plain - 3.0) < 0.0001 and @abs(heavy - 3.0) < 0.0001 and @abs(descend(0.05, 0.9, true, 300) - 3.0) < 0.0001 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // learning_rate > 0 + invariant sgd_constraint_0 + assert valid_input() > 0.0 + + // 0 <= momentum < 1 + invariant sgd_constraint_1 + assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0 + + // weight_decay >= 0: a non-negative decay never grows a weight with zero gradient + invariant sgd_constraint_2 + assert decay_step() < 2.0 + + // params.size() == grads.size(): every parameter moves + invariant sgd_constraint_3 + assert one_step(0) != 1.0 and one_step(1) != 2.0 + + // If momentum > 0: state.velocity.size() == params.size() -- init zeroes all of it + invariant sgd_constraint_4 + assert init_zeroes(1) == 0.0 diff --git a/apps/website/public/widgets/nn-sgd/nn-sgd.t27 b/apps/website/public/widgets/nn-sgd/nn-sgd.t27 new file mode 100644 index 0000000000..6efd6e901e --- /dev/null +++ b/apps/website/public/widgets/nn-sgd/nn-sgd.t27 @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-sgd.t27 -- gradient descent with momentum and Nesterov +; Source of truth for public/widgets/nn-sgd/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-sgd/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/sgd.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 16 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets lr from 0.01 to 1, momentum from 0 to 0.95, Nesterov and the number +; of steps. Every point is descend(lr, momentum, nesterov, n), the spec minimising (x - 3)^2 from 0; +; the dashed path is descend with momentum 0. + +; WHAT IT DOES NOT CLAIM: one weight on one bowl; a network has millions and its bowl is not a +; parabola. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_sgd; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-sgd"; +pub const TITLE : str = "Gradient descent: how a network walks downhill"; +pub const DESCRIPTION : str = "Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever."; +pub const IMAGE_ALT : str = "SGD card: momentum 0.9 at lr 0.1 for 50 steps. The green path of dots shoots up from 0 past the white dashed minimum at 3 to about 5.1, swings back below it and rings in toward 3; the dashed violet plain path creeps up smoothly. Tiles read x after 50 steps 3.09149, plain 2.99996 and step 1 at 0.6000."; +pub const HOOK : str = "lr 0.1 reaches 2.99996 in 50 steps. Add momentum 0.9 and it shoots to 5.13 first; at lr 1 it bounces between 0 and 6 for good."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/sgd.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 16 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 100; +pub const K_MINIMUM : u8 = 3; +pub const K_LR_LO_C : u8 = 1; +pub const K_LR_HI_C : u8 = 100; +pub const K_MOM_HI_C : u8 = 95; +pub const K_Y_LO : i8 = -1; +pub const K_Y_HI : u8 = 7; +pub const K_Y_TICKS : [5]i8 = [0, 2, 3, 4, 6]; +pub const K_STEP_TICKS : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_LR_C : [4]u8 = [10, 10, 10, 100]; +pub const K_PRESET_MOM_C : [4]u8 = [90, 0, 90, 0]; +pub const K_PRESET_NEST : [4]u8 = [0, 0, 1, 0]; +pub const K_PRESET_STEPS : [4]u8 = [50, 50, 50, 20]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Momentum 0.9", "Plain, lr 0.1", "Nesterov 0.9", "lr 1: it bounces"]; +pub const SAY_ASK : str = "How does a network walk downhill, and why does it overshoot?"; +pub const SAY_LR : str = "learning rate"; +pub const SAY_MOMENTUM : str = "momentum"; +pub const SAY_NESTEROV : str = "Nesterov"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_PLOT_LABEL : str = "The weight after every step, from 0 toward the minimum at 3"; +pub const SAY_PATH : str = "this run"; +pub const SAY_PLAIN : str = "no momentum"; +pub const SAY_MIN : str = "the minimum"; +pub const SAY_X_NOW : str = "x after the steps"; +pub const SAY_X_PLAIN : str = "without momentum"; +pub const SAY_X_ONE : str = "after step 1"; +pub const SAY_NOTE : str = "Each step moves x by -lr times the gradient 2 (x - 3). Momentum adds 0.9 of the last move, which speeds up a long slope and overshoots a sharp bottom; Nesterov takes the gradient one step ahead."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/sgd.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_minimum_is_inside_the_axis { + assert K_MINIMUM == 3; + assert K_Y_LO < 0; + assert K_Y_HI > K_MINIMUM * 2; +} + +test the_presets_stay_in_range { + assert K_PRESET_LR_C[3] == K_LR_HI_C; + assert K_PRESET_MOM_C[0] <= K_MOM_HI_C; + assert K_PRESET_STEPS[0] <= K_STEPS_HI; +} diff --git a/apps/website/public/widgets/nn-sgd/tool.js b/apps/website/public/widgets/nn-sgd/tool.js new file mode 100644 index 0000000000..64989442c5 --- /dev/null +++ b/apps/website/public/widgets/nn-sgd/tool.js @@ -0,0 +1,42 @@ +// nn-sgd/tool.js -- lesson 16 of neural-networks: how a network walks downhill. Gradient descent +// moves a weight against its gradient by lr every step; momentum keeps some of the last move, and +// Nesterov looks one step ahead. Every point is descend(lr, momentum, nesterov, n) of gHashTag/t27 +// specs/ml/optimizer/sgd.t27, compiled to wasm (./logic.js): the spec minimises (x - 3)^2 from x = 0. +// Words are SAY_ and numbers K_ constants of specs/widgets/nn-sgd.t27. +import { descend } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, say, source, svgEl, tiles } from '../nn-kit.js' + +const NMAX = K('K_STEPS_HI', 100) +const MIN = K('K_MINIMUM', 3) +const ctl = controls([ + { key: 'lr', label: say('SAY_LR'), min: centi(K('K_LR_LO_C', 1)), max: centi(K('K_LR_HI_C', 100)), step: 0.01, fmt: (v) => fmt(v, 2) }, + { key: 'mom', label: say('SAY_MOMENTUM'), min: 0, max: centi(K('K_MOM_HI_C', 95)), step: 0.05, fmt: (v) => fmt(v, 2) }, + { key: 'nest', label: say('SAY_NESTEROV'), kind: 'toggle' }, + { key: 'n', label: say('SAY_STEPS'), min: 1, max: NMAX }, +], { names: W.SAY_PRESET_NAMES, values: { lr: K('K_PRESET_LR_C', []).map(centi), mom: K('K_PRESET_MOM_C', []).map(centi), nest: K('K_PRESET_NEST', []), n: K('K_PRESET_STEPS', []) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_PATH'), COLORS[0]], [say('SAY_PLAIN'), COLORS[5], true], [say('SAY_MIN'), '#ffffff', true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: 0, x1: NMAX, y0: K('K_Y_LO', -1), y1: K('K_Y_HI', 7), xticks: K('K_STEP_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_STEPS') } + const p = plot(svg, o) + svg.append(svgEl('line', { x1: p.left, x2: 640 - p.right, y1: p.clampY(MIN), y2: p.clampY(MIN), stroke: '#fff', 'stroke-dasharray': '6 6', opacity: 0.7 })) + const path = (lr, mom, nest, n) => [...Array(n + 1)].map((_, k) => [k, descend(lr, mom, nest, k)]) + p.line(path(s.lr, 0, false, NMAX), COLORS[5], 1.5, { 'stroke-dasharray': '4 5' }) + const run = path(s.lr, s.mom, !!s.nest, s.n) + p.line(run, COLORS[0], 3) + for (const [k, x] of run) svg.append(svgEl('circle', { cx: p.x(k), cy: p.clampY(x), r: s.n <= 30 ? 4 : 2, fill: COLORS[0] })) + cursor(svg, p, s.n, [[descend(s.lr, s.mom, !!s.nest, s.n), COLORS[1]]]) + dragX(svg, p, o, (n) => ctl.set('n', Math.round(n))) + stat.replaceChildren(tiles([ + { label: say('SAY_X_NOW'), value: fmt(descend(s.lr, s.mom, !!s.nest, s.n), 5), tone: 0 }, + { label: say('SAY_X_PLAIN'), value: fmt(descend(s.lr, 0, false, s.n), 5), tone: 5 }, + { label: say('SAY_X_ONE'), value: fmt(descend(s.lr, s.mom, !!s.nest, 1), 4), tone: 1 }, + { label: say('SAY_MIN'), value: fmt(MIN, 0), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-sigmoid/card.png b/apps/website/public/widgets/nn-sigmoid/card.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ff4df0bed3e3a1187e7894fd99b0ad288a2627 GIT binary patch literal 43774 zcmcG$cT|(Xw>F9u6#*L{A|O%)0Rd@J73m$Mmq;%GA~irLHbA=c-b?7Agx*vHL`vwP zC7~mb5NZO1@`0Xn?^?gRzIE^U*1CU9$huQgN%%fQd#M> z4jI|yN;0yGUe_+3ee>-xmV%7z7Mb$vmv6k&v8d~^_dHL#xA0|8d)a3%cwb=pLY}`| zKBwoiYf#h21LLcG+RR_0TT@-V`=l2N_uc;8*O%9kHySTF(lYp3l8l;aDHdpCeIoQe zyVH&9$3;A{Cb}OKg~~uN+Dh+``j4=e&lV-qVxPQz-e#*jzI85zERFo5^N#o2VY1iG zJM`{-xOLu^a9w0MZ{KKNes$g!<%ZE*lc-M&3H}v25{&Vpf1G#od;+pcDI+6C+d{{x zA_oVfsdo7RK>2156^GCIla$lKWZvJs%nWg{G#AbvonVvKF45D);wYn{t~!gc=6z8! zH2elcnYJBkr3%MRh&4L5Z23t#{1t%vW;i|?#aowc6PPC2*+Ut38kA!oWT#FzW-)rlGjd8 zFI$!_1=Bl^NCt{=ME%=0jSh?OXZ=eSJ6#7I$~}K~R`jKU{Z^A6f_b1)OYX07Xmn~F z*{MID@8$jP$p5Fpv;;NSmfc?B>Me<%b5)e3`GI?0u zsxn};60vc5!eF&+FJj;Kxyq`Guy-}pR5@Q4>{No*7tKUvwb+`K3evH>0@s4-5>h>CY5i$7yj~i z!V>+Gf@qUfw5HQ?SFhrN9MrGLrdQh8L{+ldy*Ekss)z;T5*e9I5J#SDr?vEEk8Hi> z?2z8vnTg&lB&f$}>&CT>(1EVYa8 z4HTRiecLzBx_oyXN;iCYboA|Pe5Yb`x^UJ+PpqBy=R_%V!*CMaRgz8>uv#Ze;e+D!KQ~QS%XYFL*GTe)I+ET;pYcUJHL8ql5;wWh^oZCxPp8yAe6`~ma8|G8HsMR zMJLyp%eP(N$#U~T&Gw-9$zObFAg20n<`cLT_19s;Z)c$-_=?PnJgCV=lDCL!zg2m4 z)`pu&+Y&RvxFS$-Dt}M6soA`Pfosv-3n%Rv-u7{w4u))RxH|{5y*Y+XD*ir*6{VFf z1rdzX{6hTcGf)#SO%@uIW&j3 zGUb+;Q~}q6TMs-rjfM&m_LNWR)cIVP;I(RA_yn)5Oi#fvNxCPC003T-vVw{mT)V zv9{kc2p?pUZiqmjaJ40CL70R_5-o7O#G5TH;a@MDo111jQQ!wb~#_gkcGw2{Or=o zTxLDIr#Z#zOX9scA;F&CJ86F8>S;p726D&yy?NaeRZ`n`bAa8h02gntHz!DR$h@l` z*1g{dv|V>*R96q~KMklLT%EBZ9<_0fqhQDd0B?$r5_N&OKQurT;)J=XOcE_OYsG1O zRFvh6eta>fNBHe*Wo9}1HnEn+AcSqq0gT+iYcS}ibC_r1d>cBkGWQl{QF~i<-QZzB zx1L01P7%&Ko*^XJtZ{!a z>3+4>UZI@!{MtKpQ1&mxq*P@%$nw|8{g4;9E{&|wkzPOF-V${vob|-~(+l4}2bGX^ zzA4T1KT~=VRs~#C{k{jvhQFS;0{xLS2qMq?y2q`0+sxHDWfw{aW%~#(hp8mwCc`u* zze1yD#`#I2D$Hh;ZVU}0LZElTTOnAsA1`%fD5ZEEYM+8>K?=g zo$$n%^k$keYfzs6Gi!FyOrBhved`}Sp!aRX$&I)!Q3!Z%qV{Vo0T>wV>5Kv$9f3n? zf1kc+#Xp1?5U4dFmqy$$@5P<=TCQXTmY#Zt^*)4njQv2gn;k&Hrk_U5!Z7%7WE&lj=Oaw2pa+N%-vCcZv_7%z=W1WZG@fJ_0|{ z_3M=qt+iTJZl?9LF3!F(&Ai$VFOpLMOBvxADx+@U^#&Tw$zDvT>6#R%oUgS~!a z)OC`a`&9zdgxy;_8iZ4(!%KJg9;B+7<1WJOR3{|xjiJ<3jKkga>iCtqEIz;EKBz$? z9^Ga4?We&qugSAO^qP`$!lfn%9cxEt8KbD%uW!&5+$dE?>+$ZN^&zi6kIHZG+3x9H zdU2C}*!kN}8-Xbc*LHymolRXl{s@z)2dIPDq74)z+Q`fJ=rD3Mx7==Gh1z4+X{L$z z&{-Jedy{!|YV44qvMq6FdPPRmXFIKQm!jy-tHf4upY4S>jCq5oau~bY#i0$2)|36g zH9eNlPVa8gisS@j^b?|d7*J?5{TP2cw#^;AXrS-FPg`^NsR!f|b=!cNzn;gSJqvq&9rQxJx>kXgd{IAi9oEZ^x_1?8OIz5`Cf7VNnO5KFFL?)o1EfwYeD74fd&L$rYV^KRj?nGar zV*=Yt*mOk4Rr6d|-?)I@@cm<4FW;U5nV`jS)d8DdpwSzlEIC!fNQrEt_fVJ@*~T35 zHv+rFeciY}r#6ozE-fj*DXAfFC+A&_5y1(a_q6E=*d2GRD z)IH^@&pFLvoK&{2mIV$pGP}Q0%O^;TU;@l&B}+LiPBoHR8$?O5=6*$RKg|<8^n!ow(xO z{gjcez1B5@g%Z2HB%JSCE>gzL~h|j5R zD2_OA6Yi1`j1#vFw9bX^t)n~jeh?md?rjX|`!No8$Z2r?qP*4UJXu(IWEVAa&nEF_ zYt~IHqo5PEGUxbk?;3XM*|TrFw!a1s#@FN3C^!7P);?DpURWMTC{1*ZUVXm0WP#Rc zS@$nv1aoWvn!W7Q(4+a6ER+rUjW=tcP|now0N9qF0oo2oP!cHTJX2vMcW<5X!0Vj0UtI)%ZO`Lefv^#5Hf$^msPL|VpK2T=Y)NW0X}q*l5QbQC{V-sxe6 z$N6G(GhYR!a~SZq5+s)Ypeq@+k<@3YL@ERGwf-RsXdYXohAbkA3D{x9;IXy@Wz2FI za~-0yiVp5nfxTzK^@UC^mr*A_hbMWZ-)oi@>{@dz78fv<$-s}7mDiK17go{E4CXF{ zwi;oQ4~mgIp7{BdIxtL57N&tdT+$)2BGPY!s@(#C-6wufbHEVAQSY1we@~YI;0tSW z?|gS!khLMe(lfM@JYGAJ&DTaDM`h?wo;j%(@8Mh1ECElr3TH`2^ORn})PJ{l15*2_WUF7-a$d_CKWnU6-m^KdfJa%Ow>@pY9-yW*NBDe02sA{}hkGo8?>n{5Kb%>MB|= z<8&HL!-MU1h(c|j>8edQ1kamxsB)II^}6^y>br)4&o);EM3X21@SOEh<%+|lpwMaQ zvlGg=kBVh#_1)RoE>J3pKQ`-&rY0utI+Hre>XU@B(2b6eSFixe5cRYbU!{vA;oh`( zIQaVy^#u%WY;|dgyvy-}O1th+vEI)3!}j|&<_*%->(AP&fFd5p{`kyyTkB{c*+i)c z|81{&3-@}BEecGVb6~{2mvbqjzCvdg?Krmop^q#@6|Q9+&iLHpYuc_KRztJVs|rHL zHz7n=@{&TExxbwtm|29nTrh)phqOw*9ZjF8yaX)>0W^0*2iDkdhqMdZPu(Y`qLEQ} z*CfnBxaiG@gcs<{LwVp%J1UE9!_B#GD8@p2xWWRa>~32tm3prkIGG*DpR?{Qkhtd1v zwmNBm6WPHM*RVz?*8aKam3|Y?nZsp=NLu3`xm|~2TN{E-gW0wfpUhYF(!+M^w!ClmxwL+JQ8e$rP+12eF|3A>2~c%r8&N;W-iq& zi9sN&w>OGp$`zxxbfq`!L_*4Z1Lp|#$8yt|mO*QYpf$QerNX7sI zYEZ~$If_gO(AnD}#Hwl?lPR`3Eu|gMamM`+54`S}r%NOnCcuFwKR|5SaiV8XvPt*^C}DBb4zB;Q0EWNP8MqiaJK&W|3WjTJ%iKY$rJ< zuS9?pdD74{T|kR+Y2ns}D{}L?Rrk%kkrEsnHv7pypGoB%MN3VV;yyvHU_5_=8+jz2 zmRDCkl^bYk{Az+WKq?`RrPuu6EpEsIp>gcnh@T9A@2hgSm{f{%p-kFkhVeV*el7_F z8pG3E*oPj_L~_;LE~@q#Gp{>4PNGix6W15I(W?eOGa~!CMf*(~cwe>`ln|Vw{98a? zneZkbWB=4mJy>KQa4Eq3+X8+dLkP`Zby=!jvBJDkWJr#}DpV2KCUS!74>Esh=NUe* zhewDzkVu-E<8>ayX7fxLunM!T(`Y;TTho;^{`L>`Zs_+0NQ>xbMhOdVSn%P^M&^P2 zmlwnt9g?GA{yTeD+7&ro?0b$$ucU8Lp_i0Eoy)Q1u=7yk#UKx4A|TgYkTU#eJTEW{d)^U^y*}lLHijML^9x= z{&7Ln>8gwd8QI&sYoCjrs%>02?uy1iF#zl7^fM&fUeVPe>oDJa#&tT;s4JYakJ+(# zJzVF^-7NQiGn&`_GI?6^x3B$uAgp>yz<>AP$O4kbeg5G48-Iq`OFs-aKAItdPbw8D z|B{$*UZ8?ouwf~C~jP2Cfmfi1k>uH$Ll}C>M*W}*S)uW@Ms^f+FH6kp0+JgK& zII~>~JMx2Nx>EPQ^rF*9XLwSdZK<%I3X7_KDMxcsPd~4`-qLbTS8~G-+cR45j4{0z z&c1$h(D%xgs|>B#`vCyElb7M)!1^IzZJYAVo%4BQuVj}vs;KC{`cd%1j_2`$jd?7f zzV}e(C$!>u8Pr@UKHqxn`nlxaXl-nYX~P{w?AY1OR8)Jp-2#Rg&%QsSc)kAdow5I^ zkpD49{GSt4GhM^2!|6pGcHc)unhI(#-#BqNSy?A`H4-yVhISvV9Hqp9+XM-%l&+73 zCECPKJEeseknP(urQfel-AhW$YuopDC+A-nUt;&*azWcI`p?`Jb7^r7%*$tu8a zZc-FnK)ZXWfMFS-)!0U)9bl)BU436xx6tG;&(X8Ad1E)nOr|fj=D@I8-|a@j&Royk zk4I)YuSEG$33G>5Jxs@Y;*pSLN#c)+_rztH89u8OxGVnn9{agw-aF}E%F&(u6@sUT z#i>e@qz3Yw6$1fD>X3yygd;qP6WIi&7kBuKDK20RXqMs@d4sT;pC93{&XZ=9?Zb7^8s6xBBjtVkZV10&yh;JEtCU);rk4c>l@IV@Ua#Q0w?Y)$I=+D0+O$;=saZW1^w*E2G867|Do@ z^<=QZUt-=(fx%zm5IM|!Cr>i1&S_!&&Yjq_YeKOduSCjDdZmky*34i!NY59ES}-z& z!t*eVGzqvy0(Mu7=Ar?=8#_Y0u)S%#61O-wv6Hnvp!h(1wt21N)H;mGqXw34E`aL? zcRXkn3p75B`p|YtG4N{;c)MTvj{)P55ie0tGhbpu6-O4f^?2>tE`*nn7 zA!F@u43_C?i=W%SDWDHqb@{C%l~C3>`dQbNzA$yKbUNJM>*QwA`wPx&l8;}iej@yJ z{$Ezd4}LV5Wyw7ELZXNmsrhm874#Hvl>*j3W$-R2)4#va%n!?d`P9=sYbS_>u^H}h z%JNvmF6{JkbU<3R6mr19{X`7RE9~K;uAp1ZkYtOzHGb1KQ2wj_@%<*hL&;-aahl!C z>eK!&lMD&N<4b+$q6Z)TF5M8DQyEIHO=`>7I+TNzNdPfL?ppqIJT;B`C@lW*-eGIg zSw7`EkHu7Jqtop~`3_%*DLA5M+VfU~^#*N3=~1k`}|Iafd{z zwF%ZDZQdTGD3w~Bj+I3iK-PP^n;PT4oq!04_*FDk9U18IxKD{{x^}h$q5pcKp1}>g zlB)9}){0Pe>^QX&!Z+Ty)E2OZ>%7BsWYF;ZkCel3S{(Bq04J*-GUr_d-B}t(_Wtpi zXVTLx!1KYx(h)$qA2e{gLY}!oO84EbY8a-jpjmtkM#BKcT|>hk??*Hi2AX6Y^%YUEp6`cBXa7c&X47F8;efIM*7W4*Ehu+Z7xOOh(wYb;IOjA}xtAbJS2YbfqzW8_K) zN>+QKynp|3nxc=(HFOm(W zD%x?W^G?Ijq`SlUPWBdZs={>rZjUuov?pO-gcEG9fCm4{B$BuIp;DXjx{pHp_U}$M z8~!I|?HXlE?$Yi9sDkj~TlmD6kH_Dn(zGo9Er2@dZ5=w7;<;7vwV_Slc^p2>k%s1%bUw<%OFFxRo%vof zM#OT|?xLx}5F!RYQ&nm{A}b%C?fE?=4?4$rVrSl(U*y*iS2uv``%(GYnnB*=Bb=E7 zzI@-wOTMi5IgjD+zhw*sQX}}7**}=)nu6&FqF*u|_e)xL=H#w8nX2aUsf5WpX(e(e zKHVxYFO#Nm^7%J5_up6(ZQ;+nk_FN2_njId(+TLSbzci>!;{rZRXwWe%cJN|=KR7M zQh(+Y1u!}X{u|l%Z=|`lG6?;)mFU9&ZS6QkoBfoO-tf&@7SVu&Op%_N1{wbKO{wDsP-D7ypqvV^*L05k$ zz6cGed2`LPWF0^LfSNP3^pW$^TB6bPp`G~${l5we`fDYv+xH$^!#g=N6Jrm^asE_} z4xWyboUJO*SA%FfO2txLp209fT?hTj&A*~^UtB-`p%)usOO#7rT!{eJB}J%OHnP!t zBSkvc$jjvR}^=iWx#YiTD?^u2?90v*3}7gF(b=`$jgx z75Od8iZ7!#y?svtZ81g|^T10|7?Wo^o!JaXxsOA{aSMOJkAXLNUTWS()_xSV#-(2* zp)8qO{>0UG4|HZsHoF=qnO4!()Sdr^WUp9A-J;z&$wglf>@ky`;jpk<%;*p-uHR2^ z3_(qeq-JzBdm~njw7!g4D!B5gs!AU%lr1Hm+&!$@Tiu^Hrj$D+js7Sl2^#mPb~d%~@mZtO&Bj6^*6_&6)BI*2?$FVEGja`y zXj|^L3Yj=Yt{fhmp`J;&x1C&B`FXg}dTB^) z+}SSXsKr0o_C|p*k*_r$Ry&od=0ghHR^HWH=!#4%ZVQrfw~Y65GrWp2n~^m#(d~OB4G)_ZCqtxV_V5Sld>RD$>pGm3 z&fSM}pG0lG=z7xe-lB~W5-J;&pn=G<`CzD-EBv>PiRLk96@b1b|K#A8f`hYt+FadWGhvijfUl>#-1MTo&BHfN6z*Em*d%&Qptv=`dm55qX z$>a6(1M4n#m^IwTcl!^N#0YUbNO>$1eADqf6Vs|nP;t%--`$P1=`JwvcfD20|J){B zE#{7rW+FJ?wyvU2S>FaY^>&S@SXW!#O7X1j`1DN^jS+!Y*yTWfrfWpltz zG!)@P8V#pMnyed27SEAh@z3Bvf!+p1dnViICL~{Ct&S-{Ju6ej>T|Tny_)%APBhBS zb!%OsPQ5S8fY52G>!f~Y~GQ~O+&{T>DcYZK#9I%{z zW-79Tv_0ATNgSS~s;)mDCQ<(=2v6&q>(I697HV)S30urTw?bUvxA?p@=14~+g;T2ei~tcB4r7;nVAec z9>Mjs^^a(7lY&2S?z&xXWdV7IjCQLxoF+&`+T|Cb;oN$I&j%!0JoPte?SKBnfPzx%E*5tFV0{2VSQj7 zx9=H8-?n||=0hs#bJ5?Vh@^ic)o&2FL#W)63z7_wlzU@HLUrurPGVW56xyL-ozkg!QhttwfwgB_DwmZmsx#5W@od1 zY(A#35}en_;315?KP!!$!0a?$?fyAM!>hF2nGT=jih_I5a+K#y$l^@a&79&Usi~U=0WJDCObH zsU!BTAM6In46yf7y9Z#;2!;J9C>o{rjZ!t1H469Tt7VVaUI$!U&|$cmW&kR}=W8=i zF%N$Q_p0f)M2`%2!Vn|i7oda9X-4Cq)mVN}xX*G*Oi1R@(L{URSK3p;Mr<`$ipTJ% zc4Qv#tIhBUZEw|>yX}FRugCY{)jKtIxLhM3;vOd*Lov%4(3b5iG|br6(e&99X$3Zf zJ??)D1AQgdAG!Pai)!mhVf63qnaL+yM869%`FlJYoBWqH(72ydTCEt|jn|O+Dac9v z=QqVmY&1&hoXSc(Z~gxBX{KwZFL-Er+4ZPsJ%Y@`|gZgW{|q6`)kk-0~UL{`^cWe0 zVMb~?i;)pc_L_3<{ge_m6Ht($_CKs3{})hd-M$}|eDX&{x%xomN4RZDL-iM*$9H~q zn>nQus95iYB|~5RgOK4h=i^ZiJq`5!7-{fDi~ zy#3qQ?f!t1=tp(1xSw8Z1wCdI>}*Y!!>x;byIoIe*}D=qs3%LJ%sKUQ9Sx^V|Ek%% z_u^*OV>i(=Tx@h|H0mih}t zCi3UUZY_(^@Iw&4W@QBut&166N^mjn);ftlL2?MG1_qPyw<0CVIZ9gYQ@XiJwRSyO zGEQ5V`t=uoZ5|q&J4B^2dofGj+|pxC^IM8}TfLS9i~5$vc@n^mxK&Gcz8BdiRS&N5c8d)7xJ~8adLG|iw{6+pI5NAQ z#5qZh_EptQDqR*)Rrs@pC_Dyb!RaOa-LeX=aEkUe&cZT%=TP)O&G3Au)1wYf!2Y}M zbE6*tGUC?XV>5aJz|nXleCL;il&MC=KH!~qFj=Kf;neox`Zf}l%M`N@SW2tXS?o!- zt?wc5PVT_Ia;BYK2qya-JSNLUuMPFW-e~>$bh$wn0%oMp9AJdm$hc=jT{3rO!kI=hp#n`d9}wi?+PQL z0-=1r%}zO2IbSy^?{rz-7zn&`rox#=NROl;ijYr4+m;Co!u+vY_oAts7{8c^_}XI5 zmp8ayFk810BMJ{b1&BbZDONq!Hz$8Am_SKBgDG{H>Cq*KMz^0XGYWZSEIfFX{do1c zexfuF6{q#~MP;~1Tx&z~+8GVVC*%@W`#qL#-rOWQ=A89^&(QB1r%if6DFNPvEj=zw zrJVM1T7%e73@r{ae?lZ#kGVKkhIZN&GxT9{FIpOPTD={r-)w1^mhxLfgOCj6BhYe)O?l^G`+R zM2n}*PQd2TAFr?M8J=Yg=W^8FRR?A4W+4^8LvGocn4S^9L*&qLSaET;$cbyw;9*n5 zm%S0&vT4@H!`Rz@4r$6U-{;UM5pXFd(07 zk%e2=FW5~c>5}RJwy^j=*y4?PqNphlj63*PRbuF^fPXl!fsu64h;`iMKyT>$4Y9QCaZt_QaTgoTcm-ZnacVJ zs`mN53HXx3Et=0defoom4+@`y>^|@+YiLM&VJ8lDRz7|Fcz(LrRoPY{dg`#vmNehPn+KPw5a=E?6}kU&+G9 z$0scEF}SAW52AQOY*^mQ>*xBbh@%!Zm4~%qIv9uq55*&;(TYgF=}?a++_8< zfR^2NYe%bb!XQp6TJ>$lkLBy3;}V64hI1pGN#{X_mX*)#Y=N}L#NR9x%D4Ts$$svz zWU@EfgKrgmwbWTW=AE~X=abGg)h4ef5tJ}=IenGOcjN34vebxNL3j7Bv8~5b@tHAux`dU9kV3yw34|;H>8>{@?F|{QowAUaagypPa+&c`9vYP|&1I zc2B<5KCwpGjZaxBj!n^O$@oAt_NuvxnPx#nNP`&9#cVD*-BEV|H$Hu-yXC=|@xbL- z)F?Wy&A-2iP`jq@?sl6@zA@fcVByu9t{`{%6-2%wQyg#!uaoy7Pt}av4mW3M$4?gK zHWcg1CnXO_SJtFbkK$j}>6ED6^-QvB;^8Bxcz>+Mr=Ky}%1U%(^4b}Z^Q*bOjY^m5 z%dBe-k6(sr@(c;>kHViqzQL3d1a# zEW=#RTM+)NCb_Jl4#iDn+))Q5xZ@xCAH3=z9R*htMT*Co$(0ZI_{mrUt z!aMhomStFOokL;WHo~}G?|8k^xUWF+6n_Duh(Tz4f=0J`Y1+=$A~!GTCFP2VxGYWl zDg2CD*NwvQEWcXtyJ&mmvV-2o7zaA?qdnEKAeC#`KjCs+B4faMx8g=V?jzXGpJ8Wh` zBehqQKYgp!hWD?i!H3H~{b2y84N-VgJ;dy%Xx>zS@KOe=w~Gq#sgRk*_3hjD9te$@ zc#aVK6Dd~0(ob(=z9Eb;j-aB#g6|Ll=*w><8ZzYTX}^JF-KMdUtb~G0b^bCHgx18! z^I~=((#im_hib`VD5R3?Mozk>UI3-8FG*Fs`^SpYJgZO^g7L&#xprhI|K)5`x~7(h zljsauuXt7eXL_M;q(5_JjL^eY-wO7+2E9YF8}TU~EDm_k2F|6X)I4ufJWZ^z--$k6 z=*V?3XT)}m<^8%FI<{@@)gsPZS~!v_sLxjF)`NRS&(zXu_~+D>g!}@P$V^4qdz{2> z72KqHn%`RY{Sk%jmzp@~^sj8aqW3R<^Hf#QCxkrMSaa68A^zR+*}nQoZfahQNODU0 zt@b_g3-3_XI&s4qOl6bKUkx!wH*=phG}hN-XftU1dd43u%|cdTGR)q45>B^Kg3PZp z%Nl#a*ji8u+E4>*Xb%frk#*1_WC=|$6ts=`hDC`gBh%bNR$xVmE``3gxEM*%+yst- zwxlt7(^PN~(;&Ou{?Qa{>?WW2MHR)VtxIDO9Hgne^8Uf9U;|{Tr+e^9mQ-w}r!rZ5 z@No|v7KdGvFmBbZ+moG``Ugyx2AgUh^4C_iVItWbld6(3wyi7eq()Zn6A zGenh{8hi9HXh^rnk;Oj{=G_KCs7pUo)<7~^=A5q&UCfRzdaS53&mg8>FY@VZ)*4rI z_8p@i5YJ0orms?mzoDjn@?5g8K0C;{)UPWWKZ3v5`z@P%8)8frpQ+k&oda=oywIy6 z1^{MG85sK{>!9+h&;Fgd@MrWvhllWm_=?ZFmgBd&63f;($mEq8xPnG+>4Q?3ukl_# z?=4jA2@M*%HU3LR?{1oQwKU|yJ-+XjeEGqH18Z*P2fbYMK_Uwk7-DToG#ri`DC}Y; zEleK(DkwBP9mO5Sfvu9Yp--UH&ZN0^3X!a;FJi)s&$i}1P-d{Rdvwkq;FCX}%+7(K zdpmd8{#gFNo4swVmAYvm82_s26hvlbl{h32i{1)N;rATFt0%ZE4~{PZcxM8* z$I2IknA;}$#aE<$I{B>>L=!ph`zy8{d|nB2sPS4tIy_)N9}JYmM7rIe4{7&X&hY=h zztl3;rsXXAkYm)&NjivRzq-p!VtND%QfdTof*b*&o9f6&JDp1 z9dF7U_hS?02Z9Z)29$K-tpRfqr&6(xqC{o37AGPKU`NDJ8aua#$9N{Gt&OV#v0l5= zL8r&75hBF_r<`_DlW#C?3mRAXO%H=ah8tH|-LtS@pQMNF2XRo0w52oaCRX4CmBjGS z*J_!3n$Iz0=q0TEaE4dIpk*tLB6A-RcK5Vtzd<2f5zWK~I9h2BETm^3`uVGjl+=Jt5MPVV4i{9b(2RD0pNGOC7k==sLF!co<68 zO}Lxo$7QwZ4lu371Et^X#$94)P@0Ot)1BC5wBdI)NQ;5Y{b*um*354IaO3)}e^#Bu z!*`7Vf-dWv(S4GZIHxj$!Tsn=P~|Bu1%w|Z`bzaHQq-%`A{6ZKbX|fjU)8 zq)48!IbvUTozCx6jw^=FMtQn$CXxfFi_3pw&T5OFSrw`aJ;hPW2yAS`jnHN#M#Njm zwCxY%Cj0s``MB+G9+RYxgbFO8hw6<3yq8kU2vX+heju0}^HDygSAyN6KM-x|U8ewr zWHAX9EeufaUjFljKU-Ttt%cOzKO@q;yaBsI&0esnPx7tPZ1{nLd81dntn@qH9__>_3LH z{TWxB>2wz@H%I9{*1C&IF(pgSE|TktWWfpg^U>vow~vQ6H6o)P7Rlt+I2qnod+<8Q z+R1A=SprqB7U;50?+RQ5`mgWcya3?dZBf941(vW~(*cr@gzSljw_#>ZC)b%bZnc{* z`!9ZHnFIOz>rWs4FgPYg9wfR$a?SLM_=imQNn`HJna+e+3L?sNF|wfBf$Z~*Ull$W7H~7(d!Z^LMyFMoHLq4z zv`ZnQ3zd3+;{lymU?n|&XG@1jpUy?J;lrnz-~FD3hUgry64XCcJdjOpOOQAqjP`ezpRg49^h&+tV~`27w$jOH zyNhn9AFHbeE6_ETU$V)+2eJcI{S0QJ3Uw_3U{J}T+$??=K$T7hYSMo9rW1~-UFP|B z%OUPdR+26RM4EbsWUAG)*{t!EOQ5iGx|$ z=`0iDr>iK-qaA2@l@qkmCrUU~tni^2P2RB~FP-KIqutWPz(9?sDzTv>$2BFf$Vws) zh@P3*3oGXrTK-ifHxxzL0=sX-w({Zw+9B}x9b0F!yuaO((7xpUbx~UnCLz~BSy+c^ zpk&7u7dHnd7yym$u$VLf%=c98=m+#DAZW`S*_gyq?W@vds#(YLoOSEZqK>NCM9ilu z4a&8~gtzPNC1BmwQK|NaO2x>M4{`DDt6U^x7J6hl?mi7wJiS>@+}U~hz4T&TN0qHr zcf1@lx0>kREmyulTDx3V7V~aj$*+)od4gF$SmJrJBZkg@cjDx}BK|7-G_ls@D`91g z^~s)zcal8@%B(xp`21b1=mX&McYR+pf6sE=70G`?5*6|lp?s$)<<7x!s_5bY`jd6L z+BGnu^Uvajld|%lP?o%==YX)Ah^*b|hY`Ay%H42eQ`c#OpMeu$NcrbfmZITvwQ zz79Z7HVB$WdbW4{%kW-6{xJ%q)#@j@h@a6QwvM&EFf}3=V{*Scy0ZO4vFl@ zI$D%jU~X*IV=a~7%yXwyR8=8tC`uf}vJ42rrjF^?pWi5p@p>VsjB(3gxS1{vSvnNw zK_Yy?4N0}A{2Fk$f}7h)R*2@b=#5=&3)M@#DUq1WUF_s@+s;C{pD*9M2~`Y~c-ykG z)To=~3kNhS=zmHX>O_gNvI~IM&oHEcqKuVud)kbyW|n&28TmrqdN`KK9zOo`VEg!k zXSs|2p0RLZB_oMCUF7hJZ#>)Z*=w`4VQSIePY-q@SvC@Ha#Gu!rQ`YGisMXm?JGU} z7>3iuZ~E#tP(&NkD!jXEyYKpr(`b`|@#5-?KW4Vx7Gx-F*HL1`Oj*~4FU2H%WH{q? z{{6pz+|cx+1z1N6A<`IpCC-pL$gI`Uk`cV%T z(9Z{@0_?o|R!4OO^VKg|DHXLDYQzoQM!%wmbKlnJm~T*FCxM%&JScJIndk3dE#U3-5)NT;leVFnj${Nfx~DPtT_+}G-n5S+ z&p5$~)oSr@#1(oP=7pVZ8c)5;?szb7*zSL6<)*`6ZqyE*F7)%quqSiB>Jc(Tleb9$ zavRB;UP;2B7Se(?(C!Y!1aT5l7qB1BPQ79(*C6>6!f8}?K5<^w7B+PxbPi&fv0<+b z@!W5`gR9gTsPM;|Rf(YpEw{+EwL6)OkAGTyFaPKp+2Fq0=fYr~+BAoc#gf+Gj5YRS z$!D5N3SQnIg$-H1DRpzQ4)pc6K3YWyL|wWFEEh96@(1j3h>k^=Zf1$rnQyka|D3qZ zOAPdQuXZg>I}CZN?SPbk+*&e~+m}-a8A4F`WaF#Aff4HJN&+HoqH7Y5>~Lk)Dn~RB zjn>B1ldthiqM~k7>GQ~;b_=KmGkfkruuEEWg10BS}X|N7cLu1=W#ZLyU5a^g$ zq3z-utBW-9Dl<7*Z8C7 a{a#_rTT-+7F?q0anBgt{qiuN=`cX>Rg(#h8EvUIU=% zS=p`2mN0D=HRI98Fipa`glO58m4{kY{ewJk^KHgh{T4>-sTSUZA$;LPoM{*;YO`h$vxpvV6fU_-6dk#AI@q@|t z$>b!g3$zl}yti8J5i!s;Dl}KTft$hVcIZw_=FF>vN>px;E=fd75q)9fnQ14|2YB%_ zY~r7Hrc<|98*Q5H!SB`v?hrlf%f?!qJ7`6v>aZfM@z|Nl<*7gO9IsZcN`bs0Ga-U6 zScH5O;c8ApKM%fTrQZrF=NjY4JGE36+auLuGD|Sv!TycJWVw*Lj&Q2M$2oSrQJGbN zK^&%yw^#esrE25tT|uK=LbhXz+N>LmkiNU8QrLTgyCvZd)7K6}-4HJBH@*$D`iv+D z@9w6 zPx`ZmBRM|DYAsAaqov0ngZZZr$1zt#BCq2;$Xo>6+tqovEU`w+mt3UCB2;zY);HUD z4N40OOJcoToJyoTlLZh8k~9mi?z25i?ZwD zM@I})B$N^<5fLOsM7l&kxQ#_S$RxR^EAeLkXd@o}|nNwEHnpEolRa8QO+nTZ;F8*XN(YPxmeG z0~(M2Tu=xJZ77zYcRFo@7n}t??k&p(EISBfkZ!EwHtlOE^;vXUx@@j;yb{{0Pl<0X zg@f3%qUjiJW+ZGNd%40U+_~@D18%M(ufMLg#(id;l74AAg1n~3`=6vtN_g)!zQe2p zZnyA1YM2ZR{W3Mib^73k@3`O726ACNB}|5WRP2Fjm?v$HNFW1xOjr_GJh0|!An@f;VA^ELD?G~v-cg`NM- zQI_3~Hj*_0sDQIG%+vvjf}xk<4L48Q?9iP#0VtO( z(*^toO(;@G&f4H-0xftkhi#~?bY!{f z1kXF1*XgCnP`yOd_U6ia<{3Lsnw(hiekdaQS8a&+>B~k>8^|rlzE5wXHMmf%1bQLeU71u`WM+P<|c4-+$1j*kq+li&`a-JNy zZ&cWfq}>$pdg*d7%0alPl#CtHYJ(D0a*TO>oG`pHZ|V#`ck>`mYh?RnGo|f$78Bmm zytS;Htog#Vk{Yv=m*h+vhIe6c%CjvvQg};;mYG8}>RhoG?X}*#0;6x>@j!R{s!nY` zYa*{s@2bF*Iyb+ye|YwKf8YS+&AU~dn`_8w2A#MlQzVCvd+xtB{4u_=lhVST`nIf6Hz(&KR|v_QJ|?+uRUGf%-|K?UCwtcG8JBw{R zciXSEB%2dB;-Fi&Tk^MS1sE|js%pwba7Lxrfvyu`YRaBaM~K8$b+;?cQjvc zQ=reu(@+uaOylU0vf_ptyi-DGzb0uMHU1K@sAaDchpp!RmY;g()DtJ!D6WqZ5vR>R z$X;+$zp(hbafL5WY8uDJ``NRVC#n~8X=e#-juwo~?S2&`wQ(TZ!oXB2P9 z>Du+MT3^Bz^+u59YEANI+g9OwLD5-o|Jq0!BQ*7v+1*&8wvZy?li zd8U{B9wp^Z>IxlP7|Pma(|!=5&9ivOUOXvsh&*@rxPA7$G#0Hz3XjE{nq{zKW~B%n zkG7ugjQ4_8A>PaJIv(;8jfU^>aAHEbYDVKZ(dSQ14uX#yT;BOs;|DsobmE?nV(b+~ znk+UE{mVT%WQTC+k}J+(>-k^m_r>@8_nVi;!U&E_i15k(-%4N0~3GF!Xe8Lo!e*KdyR{TU8=EHOskai27ipSwEaBA{`?c-fh!*w)o|9JhPuh-m9vqB> z-<@Cz(5N|ruEk!I{Ai&XA8tz3>B}0=5>fW`E!SZ7{hg=k)7*LDKCRj9M5TSyt|?Ge z+}7ISE;`4pZ z)Vo_y%FXqC!5ay%ys(~`P@QoeR46|Bl=3j;SsJh1yT8%C_;T$AM6kzlsrY9H4zc&WnA{bk?^7gtiuu{3 zJ4=V{>tY(JhX}chemF_!m&NT;9FEg=s%C|!9lMT*Tj>S=4SE94o!J`iCw`D6q^Qy- zIJc_l(07gbK~!G2!C^I#tEdgTl|snPA^P~FBYELm3xnUSLm-^;rTw%2DrJPQ;-Td5 z@MN#r6wnOS)O@akR&LxzVInTy?j{MX% zEvB_P`<21Kg01WNI%Z}YRUNEVIg*?z6j)3c^R0Tjd%XKZxR%!;+hQlK?o>D+(`)Ms z8;n|SNzQ(S+hR0s(2@VBSvA$Tu_Ya6YnI)qDx z+rO5Gxx?8I*C=$7z@AA;UJ*+-J3V>LuXSgR1mt`ypAlhnhw$?f@PQYyVk~etaF`A zpUg=0J2-rU8R&Z-W2PwO;)##g6Hm}%4emTPC{JFx4%UBt0l)X~oXm};CxlL2P=y6_ zx4k8-3X<}NFYZIC-=K~XN^-~=cdl2l_4Fd@qURbj{Y)pX9PQWV&(;g~=WgQS-$a;e z87WLPZKT9KIouxkn@d2ShG;(i-Sjg%@091=QDC|H1K;1t@!#wd=a0Q@2#c04RBYW2 zw|S>^)hOk|byB^}4H;|NP$-HO>bLz_+eY1nn1CkEi(=taH~2m0=0m6fZJ_S+0#otP z?@L#O$2Vs_%w;;${65WL+91W#BZ3(Z5=Yrpe<=+QsI*<*pChyH6YfZ6A61x)v`c;A zIi%YApk_sggH>Q6VaOits?D<;^~K_lCS175x%X^zMz@ehdk_CNWjEeDNQ&_FL{==e~^vpU0Ylg;QIAH2wN(o|3F_&*Lz~ zXbMyR(w^;%v^UOx$MYv~iUpc5#hz7wII-8#6ZW~%)1XhE-C>Ie#h;Q&&^LWVT37Sb zQfzNg&lH_2rNezl{fy&CR?J#aBeA22f4RTyYrorMf{+?IiHK>mw+l%_z+3N zakR9F+j#uJHl)EDo+pw#DAK^rxzzumV!7nDunYg(*b+Rq`8>u8{-7pzT$2sw1B?VG zgYPN7HY%#_q5mtgLWk&0*E4YzhQdJ{LRH_}DWW%`fV-Lx>h#QMOl z!klogtAkA~R(vUsm*P{BE`CEFQEAT%P9U)tyE+{b6I{*Kwlevt!C6$isVUf^kKxN| z#QRbEUQ0KXw`zw~-o0o04Mw~!xGP5m-^O-+J>Cn|B7(W}1eOiB<>+ro_&wp--oQH> z{2AU(;wjuwwV8cn5@ODL%ezr%<=nZtL*^q1I%ugadGug^Z`1~Ef@q57eDYi{0$kxx zK2H88?m9cxIio2_QyypgEFXvH#j|=xo8P&qnDt36Y%eD?;aS9Za)iWx{q@@Zqrm`G zg>(B@WKvGJbqbwfpz$)-ddas%A&N|iD zQ3ftQ-%69P<*hE%8#(zcgNjY#o(y^&gBFJEqJVL#tYv=OG-18+?XBU5FdJFS^QpGC znRQGZ)qj1!*n4b0ll}K}O zGusBr2|2>!^|x<@Uh2mvXc5;q9nNRBUGfaW`XP_g==7Qc1y{3yxRqs32HSgSG~2WK z{mq%j%YnL>Q=wC+2(fI-D3bBqDZRgUc+f^oI2y_^mGnWpXFvXAAGSCiuR_z z6@`kAX&_9)$5`wo>FxF(H&lD9WO2+iwzFY=f4ZgEhw?;@yx)aR);LclpGGG()`z+7 z31e>m{QRrwkMx(8Og@kPnJo0ksMD0Ekd7nu;TSdg3$b!QbwK$+#;&wr^+~!H)yn8a ztC$$ifyaL9h9|1k3fE}2ra708RhY=@@!3kE^C#Wls&qcPBWq9cr5UdtzZ%?Yp;T#l zf#mkjcv;JKu1`-0@AQT6(5z58s9xoX>gsLLyx0)Z6WxZo%mE@Kv zH<7U=q_=M>uNd@lok!Xd)na;@EU=Iy_=zTd*T;*tt?lb{gzl@aKmzf^a7vY=UG$#Q zC{`VATy!~O>^oAlk5C^1;A40RQ~SYJsizuCigE=o%gcp?GkjaQG#tf&9{ij_%Q&!o zzrvaTXwu?<?rjwUlrQ+ zI64)u?~o|LxTyak6(Gjt(Ij-XTHkG4V;|M`GzAqsE-BsZ{y$rS?w1@j@9%#10hWyKe4NewG$A3+<;IhBql0P9bsf9-w(RUuow~Cac8d>h>ttcCcK`@6 zkDj|pOYD3Or$fH_7!>B|5%06zyt+aHeSrMz?Cov$8p{()eqWCwU{APM|22NK5rT=-k4ZBR@RTBHlie;Bs|-o*3yV&eM#ivWLso{;PQ}6{&d+mUl9}dpUJX z?ojUxMy5<8eCsy1Z3RgUXjxQELbx}V_1MbMOWKfnsq0Fu4 z2CVR&2ptdqm}-hUxbBN!{5Z)-*iy=Bqe#;Hck>op-*fwWWbjOdmF78SWhjfF*z@2I zE@~oHZJ#AE-1}&4h>J&3e+K=EtofO1pZ*%IG9SbBelPSYL%=;dnbnAv=D))WX+ag+ zEI>7ssdEVNFOPQXy!+8=ljdb|o)##<7VpB(>oV#4``5}8AF;S!i>K%CRhzTy(bum7 ztS=m$-5~B= zCHl7m@cJl`q(Kj*TH(<9t4fJ#QdxLE-*L0x}Uw9BjV2bP8#|EwWHaMJgAA8bT|S~B@6nwv){-L%%C22Vxv3l<+Qvuh{S zZf~Ex-{!yeD*Xl0DUNBKCq)5Y;2V$S_5g4g(FlxcQ+ym4$=#CeK|ODx*1aaWns4<& zA}3EfN&C%1!6Y7-Tf;4%!K@LdNSNV`S67sRpml}HWg7hz*;J@BFp8D|7=;a#9lh2{ zs^@sx;(7;UeCSn$5Gb!c9mypt^jF#(e*=lWhfIG{F#)CX-3e+4Ib8e30Mbud(_h+T zOQzKD|BT`OjMOItY-uLOS3#jgnV&k>+`Ep%5emdA8_03x+Vml=09I^?fTWcKRO_`RhJ_3 zDxGB5N%JbEJoX~;LsuogqK2Ey*yNF^)_yNM(a$I}z2W+I#|r!6#oy0n&z824a=}%u zD(qU4n|f&xIonj!n;}Oo19zE}ZbK=larB_9BE(STVj4v}T9I7YX)VSEl4fsr z;vPXtQVPCK^oy_@XH$i;feb6W$Yf?r{pwF)$Axv|L>*b-AAg&4k|O{C#n2t&41>r2N9 zYn#Y}NzRi!xsPNZ;W)ETwx2+yU)6@U-mQX;Ar$jS$xxfba!7Y`n!#fJrDK1FA@_F$ z;c^ywc0`rD^QpF@g#%@B>HIS5`sm!%QW<5cq)MlzlabF&Nh+_7$V>yNZz(G;4X0ME zjoRB%tRY<-SmazWDF=C`s?+2R>)O3RSIsVE}7MkB<*#HDK&of zT&73t){Y?stY3NWML3oH%8{`%*6NmiFrwsPv2sx_aN8#ncFX)84Lmhy^gL!Se-!;f zrCZNqou&Dpy(V>TOXlIVpja1We32}n$7e-u!ull%DHd$1)U;7?@I!b?a07%%#>6g@ zkAI4aGy{{A;38I{&gPD5z&M&5&@k{A5)^618Ibp6QLvBv^zjp^SgZqCNn#)Yn=1VO zPgZL5^Y(Yo)VP>}9tDBMLJ(U|HFe|#yg)0ie7K19iVR`rIurMe2B<$2dD9pCpGU!o zwJ|!zRoZ9pdzpZYuLjH8UNb2YupTB#ZPrHPuIy@}QFtO`RI2cPkqO9O1OE^}$MD_o zTc~_;z2vGd(Wu0!tg-2f$QvL#8WB%(tB}Huor7dn`|iz;nnkj^hKbu@g#?bVu#?Iy^89%av4&_Oz;Ban8%vg57F7zXU5myyg70;kPPer@{W}I zGt7Z?;54oW#o;7O-{4fjf_=M)4x5XgE|_1HoLw)iD_>A3eY;L4H!DS0#}OBa)Yp|$ zxlP{tbS@TSi5{8=?$RI#DV%P4E1i)-jJWAbq@I}JO3lb91*XvaHCUcdq3l>rZ0e5e zf)Os?;iZ5Fy}uz*Z0+q@kaEAImQ4CCvR$8c+cK}7|EA2N!e)!A-*`CDw{YkR*wu#< zh4r5*e@w_<#d-Vw*?nm3=vUdVsugNiik>|PMd}rFws+oQcYl92Ppwnqx%ji@LinTH zx8By)f!5aOZ{HsBM8-C&k!RJK{gH=D4h2-HEg7cm!Sx*w?EDW7)@nC;a!12kV{2W8 z<>-kri->M2=jb62GI-%l4s==&mP%2x!_w@|j(azizsep;x*t{U$G>g;kg&|5FQdSd z79xLfn*1;zD~p#e*Pu3*7}w2Zh?Zb(>0wn$j&Gs%sCwgcw!Y&>=N@yLd_~6>x0!{} z-$b<@y@_aD`_~tMrScdVazFue=ukCCS(}?@*Yjwr@mF&oS9#o3Byw-)z=VG!Tiec5 zRz_3hc}b#iUk?R`GzHp6_sErh^HyYUT-s1kwrLQ)EmYaygVb9;8F5M)2NGU#4R`KuAw^*8jnucLG`@wX!Z_=LzY&lN3-oQn^=yqZfY;9x#qU+&~Dmm={_O|=@nn1m~fq_2x6%!#CUN%29?$O zcz&gZ!?Sj|5wL%(nhnq2LN;M*6_mQwZ0wdE{WM%7) zcGPn!49}JO9z!pfmm}Ft>+XPFEz!vvanl{Uj}Gi0GXB{7dRw+(g_*%|oy`q;pd8dS zOQc*HQ;&8N4WR=HvTmkPkDp8TJ&}3+$*}n`#P%u?wuU_@cf=XVf~mayohu`W{cV^1Bm)2fP zP5!D`dCi5XgT!lK)j{URb#&picjA|c_jPKj+^aKho2tsDMqXQ&7<^(-?C6TP&qtMY zM$MA3yy%d5FX1>`>&`fa=r&~R9=7ETlV_G>nC1BM*@}LV;IChalJcta3mHVKYSN}g zDr>uw6(jT_5PfgP?>-fvk0x>B!BL{ac19Cj-8(qIzjMdd$%#xS=VcKcCb6LA#W2fN zA>APTcc!29uiU@K7GSh!TM0G=NuQ$!TmRzkc&uj;?)i#fLc%d#Ex7#xI}hK$Gg%W<>`Iu6bI#O)=NZPQBV9 z0Q<~%6QbsdE$LGFlOOJ=kw(DGifb*Dzx;hMAljb%I>eR&dunQG1xbD(7I1|POYYm} zADMY@2W788NIqjnXQrvrvT{_>tZOOey^j~)D4=p;(!weLd(DUk`Og2J(-0FAo56oz zd3-Rsx7;tAuX1`)sOS(ebADY;_Dxj#Y4k}$jQ9Xx;2ZyWeY(MMeK>!p8FMPjLR7$h z_`E(8y}&l7sT8oAQHBU;MUZ>nhNM5na>w`Fd~T`(D&BnAR?jy@gzCZ*B}I6o5YaB| zdHRH^2&EvG>$}?&uIn4?(N!g1@clWy{$UM{;K98HQIf%~ zC4K)oF0O1>zLAYa-eK$w>x*Qf2ZfClT3VHg5J=ADS4R+OZuUY4^S*;!%W1@6DVn*M zT-F>7B8c_P%bhDi<)s|mXem&C(})ctV@7$H_Ex2FAl45r|4UtvA|{x;-$$3c*>23( z0gW_?*q5s_i#>k9K-c6WL9+_0xm&#IfE+Wfcy3g2W}1}Ah6kyQxLg_u%uzR6nr-0u z`Z`D3M5>U-# ziv5bldOCCF4Hp@%@WvOg)uD!?+5nmY)jWlB4{h#ur#GPZP4=z_U$)kK87~rUXwqtE zdzrZyGk`CcAnsrl?d(Lpq~Da9R6$Y@cTI{|6N{)P{~K)=eQx26#@*Q?#34AYXg2IN zYYBRVO62^YCb4$>%8@-HRA?71nM5znjFbX5eirTnh3m-oJYAm^CcG%IHz3bRlisN zMN#vG_dQSLnTc$w5S7BG2nKb~7ApXIeM+Q@&pI*@5o5__dF=O@opJTKb!0glyMNks z>wXwD|8PhP_0&A!mfL<;nkWY4m$57W0EiH4z={UuPh7C0WF_VM)$Z-H+(2Gf9QMD6 z=edXzx4RL2+DRZf%rgBVr58lykS@5@RTfW4D`mqQa$?n zRLVUS+m=s=3X#P-F#Qufav2p+>4hN0zN{OyS0^M1BjztC>?jxqevqHBzsmM5lK1?I z5t*Lomz?*+nqYT^+D>(PYR-PTLWRwr zhlklbArs?%&{zOcUS@Od7wWMW+A-^cO<#T!M@Ft#Q*Zi({)5rsQ&`-_zB98zSetQG zaUNB8RPZWd5g~$9lNU_M`B+@|Xs*kJq5Tn9tt6IF8M46q=jd<8Bfn^?wnG~0#o&}h z){!sWQr>GMO0dSYjqB$h!YRp;8(^=W+y)itSY0c63l?foK-nqnS#zc=d&EL()4d(~ zEGd%|P7}oboF=xI)|0 zkLEa#Qi@B-&k9|yUz@^){iUY;ypdz<(1H+ z=w7X+)+VuktP6ouUvgtmdNru8V%N-WRhEtUfO{RH)Jg%U@}0jbm=MSeW)|$-@=q_rNZ|m7f?Vas1PU1&t;6c(==5wC|D`%LzzFVAnw;S*9K`L4qkOF(R zd6np_9KvX?jnE3He?Zr5ev4WyIcR`7!xCjvaYJ6)}UTY1` z3voRD6i?tWDvO(&)c5bNtgHZvQetmII#hXGT{AB17l+hiCi++zb4o6^eVw5^9?LN$ z>}fv90;9041r5xl8hp&Vqn+NCck7?;dMSM|#+as8T71(~lVnpTkO2EHz@}O$sl)uP zE)MjaENZnP%KdO4upd}GsCEl#Pk2!1zT4fJcZcKb5s#dUOKnAktc*+$=%0HZOHhQO zW7#MNwL^J7TR-n6}@^id|>5{EtLPg3g3-3kV z?!WCeUS-1C9%$jSwON)Y5>|WqP?Z*Sv3h|6nFYMcK2aut45}ipm?hur3h`7*kE%R7O z3)b6>k9^%2QHmWNyE*vKr$AQE3C?REEbRmom0=aY{t03}cBcE*sKSp+C<~rzX<;Jd z<>rfr#}k_ZJkD&EcV!3bTEt%wE(vC4I~DiLPll)V<9Wr_&d24Qdp@6e1X1Gt(1et- zE=kjQQ^Vv({&Y!J%IUUhdTM;&KtL%wszH(onjBU`(J8|;tFO~cRY?EZ2HWaU4)rgS}j`T+t@Xg3I9 zR2V%EZ2j+~H$O9ZJ4s66mSyKXpbYo;;4+CP(m(Aq@aSMFxzfOt^HZ{3Q+mk(YesN5 z<6_twp{C`A3oGF`sAj{*3Wd!EA+#m_e1q&K4w7RvMM3M%`$$HOU6iEKQ+wod-KOg3gaMNvZZv8P#m*x6?N!@tr&;rQ?93+e^ornAsS}B zzx(>wp9=emetl(zdy*M+C~$W&U3g4kbNX?MOMhmtX}|3F^SnG$ZPqSna;s&dr_K~% zVFVNuU?I9o5~c#CQdbbSeTiN^|GbRjKC!GUHR?yR)X-#J~6zo{~Rc1Y^YxF}y^@q8y@)Y^XP?`l!qDZHq= zqHwZVk2vsc`9;v_*9ljL2lr=5Tn{}G$>@drZX6!U-#KycX7wc!jmbFT`eR$ClX`VI zy5=S551>JG^F7{kBfn*i5&`SuW6jCnw|!gse+PnI@zXW-3^1NLJ?}nmM*DMiXm3g# z?hSMNF4et5IR4CDYo`?t2cj-MlGL8mv`~2j0f!q?q!`dD?Rm}9 ziXKz;c;qV4r!7%-+|Y$zHMuQ|^Yiroxv&rjX{uW=TyTO94x2hHzNg>kNqLM$-?(vu zS3m%mc>mEQV_5aK&hjAGt4VX*0qFVv*m9&vXa$kK#SuDRr8QDdfYM^3!Ri*$_?fp3 zDshdO&#k{iwxs~o+m6kPO~+AfX=H3E-SFA%RxZQGBWKfYGU?4%&ASG9_w!PGtGV&) zhgvL>&8fsl7q*+cHX#PSKCEI@qRZ!T?OI56m00|Xl<`Oe2JJnpHf4T%5DZpjeN#P_ zngp1_U$Kg+JqvsaZc10A=9`If#{~dQ(aBg+e91)D7Y?~Clg2!?h~bhpH2U=E(-t*n zrqkxczsi~U{y{h0oLLXshEP_|I9+v~dyO@{WXR6W4$uMkmu=Tc1NjT89BiUB)jB*u zZx7u|Xi4g?J*13D_x5t_Fj;(8350F&<$mtFJtzVymX{(=4h6KKF773D{M?e#LYe`+ zLv%9YIRc9(${p9cq8N>gjIRGn2uOin3c7vvZ1+b?G#g{PKd?N(Su9=Zb;vM}yR2u; z)Q>MDi*;$&fa!)+vfoGYt=15#Vt_)cv@yUt0GX}FzFz9McHzH7UY)Ge%!eh#4gOqQ ztXZw-6a#@zy-JjDHT$A=ZDwZ1*Vi{JEbL!OSjK601CV{#n7NC-v8dLlcFjmK+{*&J z?~hN3MHmCdfZUTgeP<&1)(EyU>Z~5LI5>VG?4ejjPau~I!fPZoE48Sq*ZVyY`F{*=<=98mHJ})s>??OQGOMg`<8}t;tD|!lk@-YTHG{Qof zQns~Zfjzv!SJCpF*Fjeq(C7mkr*fzBHz$0cYE(sT11ES0Sgeng(lpg@&FKjjp`9uY^cCIRwOV!bdv@=7+lk+-M;YMQse zKEz^F@KB^dprw>k?qt;l9LSAJRz4qg$I0j7hBUs@)_LP{s*JOqE@P>Gp8Rv68 zxu2#u|GUj-u7mUH!Fp?JI&|jyH5)*@gi8RJswUM?SfA)(#cJFdY6BVI%L| z-PtLHB|J8z9T6~*TXM;xf|w|^N6pR6zP?xb`uhH54@3a^{l(c2fO1QLv=be_#AF1+ zS9)`Fvasj*3Om!K&7MvL+n$c#DQawz4wMHi`4CiCJXM}6JRzMp(#O{JxO+n+dr+&^ zY+#MsLLr5p;a|`wmyg^;j@kebs5*kh8ms>|X^=bov?)7R)tc^w#)%soyPZn{P$Nh6 zQrA;8)lxB9fb&GKoQLRB7aFj^(;V>!hrHMcu0XmRjAu0JeevbV%Pf-q4~kck93H>A zi`PxS{UG)aLLnkaMqV5Upgy{tEAR#Cu$Qk*Z?bT!?r5^V z4qep3q;L-+R&`NZ+nBfV5ZKD)u%b|Wse=<5SBVb@Z7`?_mdR^&-Jj(U>?t+h8jNQkwT8`r8GDppe9=2@b z-^4T0ApH=hEt+3aSAZ3Ujneq21sH$(` z&(Q=w$%i^}15?KKKaUS$blQ=0HKjtjTApt~m%d9wOeR1ZUN1Pr28T7)YJi7UKutk% z#5^k$z22*T1&*D9(x)6vmC!{58JqS^Ao9RxGIW+_hdg&`uUu)i?udqEiLjj?=KWrH zwOq5edb(5S=efBj`TD>3-a5Nysmj=L5{S@2esD@adcU8X!r6-FEz+7x^1;XVFh2QIeTvd z?nrZ~(RnQK@{sW|AtnFyJ6p&Oqvd*giT%|NfdVx5(9VfKPW)Qiu&S$4wx*lTZ2Su( zq|#jgYPvU|FZ1WWJ)rm~oL9o}*Rt*UE$GJTljT10`s6aFxHuE%yV3&g`~5M&-s2SV zq;x)%%=RWNXFqz1u{~G*86$*1!6`Bknm>uj(8T54ICGOXgys$m48Snf#ZryKL+;I| zs3rS+rz%RG_2K5ptp1T_%?*!_U-{xO1sR%Fs)ktJEJeI~W+rlPGs7ewhh$+;=!zE4 zXg^!q6G~H?d3exLQ^NN0ow2{>y0Lqmp9!yhsi>GI|Ma|_kbqPSYN%@%Ie(%i%emAm zNLx-{L%;I>#Mfr;ty(s=^yed?96qGl4;>us8yr^e`4WvJdkeI<{r+%h%^0vY_waj5 z0u_~97{L$JJrcwKl5HTFSyYRT=tr#9pek2;S66)PMF7u{g~({Vc*+JV`5^hJ~Mqozcocpa@W{CXFq5%;0yEPCIE0*A?z0U z+_loa{M>=Qab=(KS0bNFKO}tY%o!E?RdXx3-fO~ zPC?_JJs(w- zKT)1N8%TcWy|aH_*kRmpqd$#8&;V#i)w}~TT%*2H;Kjqx=3Up^`ESJLAJL>_2p!UX zULvkPuoZ(3RL}J``42$Wa~@2yxMdpb$I(5O1ko5D80ZjXB#)mb0o{-Fa{Am;LTyFy z6!nZ1VSN-3QZnqrIhD>Ta_{h|9|^Bd%)qNk5tkE@VFlPc7C}wiX!ih~RM;;NrX#^hKN7JNR|&=aOJxQO z5$5YyLH$Kpz`a|~7fi5t@X2uOfAA-XB&PrS*^lH+M81m{=e7R>K1*e&$F(O$`hkRJ z8uB6ru=q5PI90L0BHl{Te&>+rM((hV6T)!(W8c(W zEJ$66+fY5{XJM+_*|9Y>jf;*Z`F8;)!vPbrKAKq3DW}g;`y@Dy^)Bd`i^Xr>WF0F3 zm-cb=qs950vEwyj$6FW_pxJlm0)U2P+YqF>KnEfW`2$`~m%x zQL9M?$C%IM>}p_I955~L4{pxU`{4j85MyCy0oGX$Tf4+Bd(JEYM*n>_I4s5nJd>AT zdjhDsbOaVg7Q8sv6n6cI29V?2=nIUF6r>XnG6}bBzOUoE6%21D9 zTS`AaDglT0Aq5*IhNv+Bm?cV@qp;4l6;}5pAql59l1r~6n*}$ zFF+;<4!3#t&ZnZH;va{eQWcE-aINPY@N#h|;zSM1B7;Sv1!M?QSe)J(3Mx$g4Z!|mh`^YKPbXzG zQD7g#;h!j<{8u0-F~F<|)=n?t3{vYP_}oC`05)+siJ z#XP6K5xA4U1YP#lxa0@set<~ToHVCpm%>#MHMrM#-YO~mZlaeQF45EZclL$hJevp; ztUM@F|3nG@A3&P^Ty?z`W;2y)kV;+jxed_x7uF$s6~=CM zPz7B6uOnczE^Zk+|MU>1aYA6KV0oLFu_`gMuZ6MYY@PGN37weMc>SemYWQE%)JJA5 zCly#-(l1#EJvo@fb^L08Ie2N9#(bM7_2;iM1yaDg*zPbBm{Wz=>lgEl-@7!PeS6+X z@|U+WkebKj*kzO}OI5|vgxcdJ#6_RR+1mhNa{G1XKDZ(h#j7x{-y#5*RY~7!c*tZA z`WOQ1R6#-EAM-;rC$n#Zqbk`Rud}bap#=}|b457|m3STthXZ54@;)|v785Yh6cJK~ z^=e$C7Q6rzLCo{enz9M24N;xE9?0QIe7d9%S6mq zt8(%LCjmy3I~J2JyNOVI{Tld_?V-?uf7y=$W-vvMWJf*SZ16+$OI=@t4$QUxdxyT{ zHMlDE=P^xUil>@=k)BL`rWk0JIpGCxC_DYeif8qD0! zJ+lE@@tMPhsF|M~6gLk}an*dY)S!9G4n`Tf18!J*HejYa>n;{%j$*7b8}on4A+J?s zryfkkhSd~U6{z;6AWB*9g)Rw04V8z?$u>LK83WcVP$QkKOMIq%{+^@Q;lO+w{TY zhi1+eU2-8X*5T{o?S*dEbi(R&;T@UPE1S+UAff`K?fMSi@YaiM|Ew7mq!32k;_+@M^8Z%>W#H<(tLX3jA zC*`|;JmSGvk9gcrl7=;*OSR|nl7-@ie0lvF=n4ndOq1@I*NeHod0Q4EMI}aNhE6w0 zWT*aq``t2hO>{96J*t7aXgS+Gn?`U*0m@)qLjQGx8!H^WUtJFC$aaE{X2(v?WZzTU z)KZyOWvlzyF`=iQI4$vbb7Me6ll}aI=?nGGqKoNX{BNj2>c0GbyO__dLgTSk(8OPW z-`G}MUt9mRu%cG8AEqy~mC`?)R>O>C0Z<2b1M5 zFJ)u+gGm>X&-~CUq#=BxL^5luLMV*QUY%OQL}-#D6ty{EYH=T>ch4i^dtNzck>l>7 zTW){v`)$A0S^WxsLnYuGS1O6jn~I#s`lw&lLEQ3S+Ctj(zKi>s6vtzIA%#;{;}>SL z`jg#%5oNs|Y%HdFysi^l@8Xr+H-w;q9#c%P0yzSLCsMcq0%6Tc_d64-?)B#5M3bIB zZgqM)*l$n^6Jlk^@8@!Jq;WQIpKtykd)RKONo0~rI9?`fI&qF^Z7|YLnQG8ne;~lq zp?%w}tEVUX^RetlU7u@(APWs<^5$zWJy9&YXcF_B)+$Z2=y0$;n$5dAbhu7^BweQh z?bPeG!Pc;Oim$1_f9$N`8=Nc@mrUfWZsZuA#Ex`Ox2UeHv`9GRVd9o|3Sg=r*En^x z;LabGoDnFO2qxQG>c{368Qa@BI6M=8dMjQlWvA~_mP_V)HBLvAdG%z_EkD%vXNA zQr2s{;B_)f)wk+R4hi=jZKa*zI7Zm~R+lz9c(;oOkzw>$93n~qEJiY{31gt^Jhk%| zUOoD0dVHEiSo>q<&b&|_|GE5B+j#Nhu~frin2gZ=>N=iNZcv%VX#_^_AZ(S5{HOTK z9$hkzolg*0{P07AgU}h^*O{Nor{a-}x$%F1-b-yW(d znmTUJPxmBA|aHu^{>vhNOL?$GQBNmCh2H*SJ^n2*Dh`jpRN?q-#vJ;g_<*s&1#hUhX5iU&vB z9tYxE+UVh^dK#6F60cuV@jHA4fsB_R)Cwt;SPStQY(KISQVt z=9$;4k{DCAgIPkYDvJd&XXn}WmMo%{wJo~Kp&$y z+U@wYE`5U^Mo1;V;FtEofkM4EcIe%o<}^?9H6ty8CnaXrA<+Z?;C%Oo5jd@#wayu* z>4Yh&`?D*T2%HO^Hvbtvie9=}SX}U{W{ZmZ;d;sBLX6aKsX;kSJvic2cpGHdy)EMMZUB|-r>Q|mG-}u)cI9ggHw8)tm1`bRPz6Z(D zHY@SzsQF7U3DLq{{&8fW6QHlLX4h%%(?0yeU@E2k4F__WT>XxCSYICNACDUi0B%`Q z@4t!GYoj)%R(jt^f2(b^$Xe09HRl>6XSs8Z!B1oBwmQ}B7grgqrFaUNeSpPTi;7li z;u!1f`|R5>1X3(NV@X67_qQ@pQV#pyr-+UhZ!a#G=eMyxW(sdMHxn2xHA)jaBx|sP ze6Pxyyaf^E8?t#^u_XM_{uf*46Bf)xUiRCdilQ!1?xf{7_-l&kzMWi0)B7>UbeZA! z%?q8n4|3dP>N+*nLaw{7EiH@w#cZj-{aQb-Y#!^qes{6t3u1L{=1m8vENN!r!EY9p zN;s!Lei$rHso%D#i&yE(cd^*f07oI{lni{m+3d7W*#v=`AC`kCx%c8o?v0A1;!Dd3 z1~2FPZ~PJ^@rToddv9ySAan4Y6R$u>LOmHF=~KqNEmCf$0Qd8}Wa=i6xn*^tT8GJi zGAh~|kxs|^{$DkHbzD@>_dcPdNJvOYcL@SYw{({@sDOa5bmyCrk_PEqV3%|$X=#^^ zUAhs0rKB6a7k{7Me;fBT_uiQ~bDnda=gdHBlM&}hE8#|yc{Qi)ctAfr%z1V?qv}Q0 z^ZH>vzNOOE`lerC`zGB({cm<|1m|tVrfTDn7F5;yMxO8vhP>x!KRF*zHBH$Er!+&* zFyFn43gvmgYK-@kj^WMb#0UsxnyvIE+~}mJ;MB5vmk6=ctt`KJ6|iopHIrhADD!H`y~uh!Z`#qfcy z;jO>D!2xemZ)(T3*E2HG?z*N3^%ewt9cB~Qduf3t-T8n!VMSij9cSn+{2OVtu#^@G zjv$jg=zi`JiUMS#?==;ftos|{m0BH0KcDh*N@8G2qG8?;=!J#vCV&+Z*E@NfHoE8x ziZuFjs5aStKe~>RCEs4uA65<(J6FwOz?!hM+eRkZG@_x=`Wc`}8)-R+LOUdxm-d^i zE1jHwHx9%HQM4o64!CST{Lb;YB6D%));3-WVBMMKgGmN44Z;tx`ntY+`70Os6kJmB z|9LUzZb)D~g6COJHw!5CXvNjKw}6pCO+z2!K!Dkt880mpFq$H!6Pk-L3Ht+HR2$!O z&)p6Nx`V>r7=Qpge!%Su@9ev&P=5{$!JW8VDZSVC61D`>7@QSKpxWzeskH)^E3Fx1%tzya~GVzOI+6O z_0Zpq=!N3jkx7)M8(&k4t3Cq|sRL2`&p2Qw@Ukp6rEV%f<)mDm(j;~-vH9WL#?c~M ze^mERYvC1wC1b&P+s684Cn6-C>izo3`^E;Hc{3oYCz=LA6(`bLUID|B&dop_$@$ZG zA8`i={xZB-q9selEkayKF6xaU^|-*%u>rVOx;uTcHtnW3OyTc$Olf_2fWpo{fq0n0 zo=S2IOC0yHkKPsE*v?DYPy>tPFVupd_feg@^YkW=-ur)h2U1#J+=zLqS#wG%H(f{B zFIRHi#s>_j>Kas?CGt?m?W8&k8$#Py~A^058e(F!Lsg8!AgnWe&Kil>FR^tmZ)XxyQd;tmjPIvN}!Z z1l6)_l$4nW=J0G4J%+O@ZkKKA?KD^)1*`lsTp|1TK2+bK&g8bMk^YOzf}eulKA=h? zezrX6IAFz_OEaX?-tklZ0Gd5Eo8lsLTQ)>18~S(Cf~9daGjX--J>dO|I`rEwUR7_c z$-fRI>yG71p$ixbi&CUVw{q9CR+rj8?5}Xte0F)D)<+otbinz-E&+LDg8y%eJ zOSN%zWM>vE2wNCYWa`>ano86#I&^8(JF5EZqYGGtAD(iy$sFwOYFR8A?QfYcJf_`6 z8t>an5F%T?qKs5MJhaKe@!q1567;sfJ;D7n3oBgJ`D=-O{M(D})+Muzru(y;c*qRJq%P1?ufYtlfaJXd}^ zIi;krUXM5+Wv+d@_FL<(o&s?r%Gm6Cc8tEJ`~a9c5DU$c>tO&K3b4GP4*M-ozo_nU zUn+4w{?ZfVNrj2nHm238>+)a(?KK=NRXwi?b>%oW4Hd57lk_-67`}1Ds=TX-C=UyR zoCsh5RYwnSgQeu`_}BVO@Nn!aFEg>4od>`0(_=JCH%TupmZ- zECAr1l~9@A#gkB%Qnb{imEmKlmgHjjdFVCrG?O;+INV29%v2iDsl#18#)GJV#NFom z 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 B5_tds literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-sigmoid/index.html b/apps/website/public/widgets/nn-sigmoid/index.html new file mode 100644 index 0000000000..695b90c6f9 --- /dev/null +++ b/apps/website/public/widgets/nn-sigmoid/index.html @@ -0,0 +1,47 @@ + + + + + + +Sigmoid: turn any number into a probability · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Sigmoid: turn any number into a probability

+

Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/sigmoid_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 2 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-sigmoid/logic.js b/apps/website/public/widgets/nn-sigmoid/logic.js new file mode 100644 index 0000000000..a5ccfc4881 --- /dev/null +++ b/apps/website/public/widgets/nn-sigmoid/logic.js @@ -0,0 +1,27 @@ +// Generated by scripts/t27-logic.mjs from sigmoid_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: b8873ed230ede07279ef5a3238d93e9cfe7e5c34904a7e769deee7131e06e71f +// Imported by scripts/widget-logic.mjs for public/widgets/nn-sigmoid/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABEANgAAF/YAF9AX1gAn1/AX0DBgUAAQEBAgQFAXABAQEFAwEAEQYJAX8BQYCAwAALBzsEBm1lbW9yeQIAD3QyN19jb25maWdfc2l6ZQAADnQyN19kZXJpdmF0aXZlAAELdDI3X2ZvcndhcmQAAgrTBQUEAEEACw0AIABDAACAPyAAk5QLQAEBfQJAAkAgAEMAAAAAYEUNAEMAAIA/IQEgAIwQg4CAgAAhAAwBCyAAEIOAgIAAIgAhAQsgASAAQwAAgD+SlQvUAgIDfwN9AkACQCAAIABcDQAgALwiAUEfdiECAkACQAJAAkACQAJAAkAgAUH/////B3EiA0HP2LqVBEsNACADQZjkxfUDTQ0BIANBkquU/ANNDQIMBAsgA0GAgID8B0sNBgJAIAFBAEgNACADQZjkxZUESQ0AIABDAAAAf5QPCyABQX9KDQNDAAAAACEEIANBtOO/lgRLDQcMAwsgA0GAgIDIA00NAUEAIQNDAAAAACEFIAAhBAwECyACQQFzIAJrIQMMAgsgAEMAAIA/kg8LIABDO6q4P5QgAkECdCoCgIDAgACS/AAhAwsgACADsiIEQwByMb+UkiIAIARDjr6/NZQiBZMhBAsgACAEIAQgBCAElCIGIAZDFVI1u5RDj6oqPpKUkyIGlEMAAABAIAaTlSAFk5JDAACAP5IhBCADRQ0BIAQgAxCEgICAAA8LIAAhBAsgBAumAgEEfwJAAkAgACAAXA0AIAC8IgJB/////wdxQYCAgPwHTw0AIAJBgICAgHhxIQNBCCACQQF0IgRnayAEQRh2IARBgICACEkbIQQCQCABQQBIDQACQCABQf4BIARrTA0AQwAAgH8gAJgPCwJAIAQgAWoiBUEASg0AIAIgAXQgA3K+DwsCQCAEQQBKDQAgAkEBIARrdEH///8DcSAFQRd0ciADcr4PCyABQRd0IAJqvg8LIAFBACAEa0oNAQJAIAFBaSAEa04NACADvg8LQYCAgARBACAEQQBKGyACQf///wNxckEAIAFrIgNBASABIARqayIBIAMgAUgbQX9qIgF2QQFqQQF2IAJoIAFBH3FGQX9zcb4gAJghAAsgAA8LIAFBF3QgAmq+CwsRAQBBgIDAAAsIAAAAPwAAAL8="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function forward(x) { + return W.t27_forward(x); +} +function derivative(sigmoidX) { + return W.t27_derivative(sigmoidX); +} +function configSize() { + return W.t27_config_size() >>> 0; +} +const __NOT_LOWERED__ = Object.freeze(["forward_batch"]); +export { + __NOT_LOWERED__, + configSize, + derivative, + forward +}; diff --git a/apps/website/public/widgets/nn-sigmoid/logic.t27 b/apps/website/public/widgets/nn-sigmoid/logic.t27 new file mode 100644 index 0000000000..4e6d84ddb3 --- /dev/null +++ b/apps/website/public/widgets/nn-sigmoid/logic.t27 @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Derivative (compute from output) | φ² + 1/φ² = 3 | TRINITY + +module Sigmoid; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const SigmoidConfig = struct { + none : void, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // forward(x: f32) → f32 + fn forward(x: f32) -> f32 { + // Numerically stable split to avoid overflow: + // For x >= 0: 1 / (1 + exp(-x)) + // For x < 0: exp(x) / (1 + exp(x)) + // Both branches are mathematically equivalent but the second avoids exp(large positive) + if (x >= 0.0) { + return 1.0 / (1.0 + @exp(-x)); + } else { + return @exp(x) / (1.0 + @exp(x)); + } + } + + // forward_batch(input: []f32) → []f32 + fn forward_batch(input: []f32) -> []f32 { + // In-place map over input: alias input and return it + // This is safe because we're only reading from input and writing to the same locations + let i = 0; + while (i < input.len) { + input[i] = forward(input[i]); + i += 1; + } + return input; + } + + // derivative(sigmoid_x: f32) → f32 + fn derivative(sigmoid_x: f32) -> f32 { + // Derivative computed from output: σ'(x) = σ(x) * (1 - σ(x)) + return sigmoid_x * (1.0 - sigmoid_x); + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // #8980: through a function, so the check runs and is counted (it folded at compile + // time before, and the report counted it as a vacuous pass). + fn config_size() -> usize { + return @sizeOf(SigmoidConfig); + } + + test sigmoid_has_no_tunable_parameter + given size = config_size() + then size == 0 + + // sigmoid_config_is_a_placeholder_not_an_empty_struct read std.meta.fields, which t27 + // cannot lower; the parser discarded it. The test above already pins @sizeOf == 0. + + test forward_at_zero_is_one_half + given y = forward(0.0) + then @abs(y - 0.5) < 1e-6 + + test forward_confined_to_unit_interval + given pos_large = forward(10.0) + given neg_large = forward(-10.0) + then (pos_large > 0.0) and (pos_large < 1.0) and (neg_large > 0.0) and (neg_large < 1.0) + + test derivative_at_zero_is_maximum + given dy = derivative(forward(0.0)) + then @abs(dy - 0.25) < 1e-6 + + test forward_batch_preserves_length + given input = []f32{0.0, 1.0, -1.0, 2.0, -2.0} + given result = forward_batch(input) + then result.len == input.len + + // sigmoid(-x) = 1 - sigmoid(x); sigmoid(2) = 0.8807971 + test forward_is_symmetric_about_one_half + given up = forward(2.0) + when down = forward(-2.0) + then @abs(up + down - 1.0) < 0.000001 and @abs(up - 0.8807971) < 0.000001 + + // The negative branch never computes exp(+x): no overflow at -100 + test forward_far_left_is_zero_not_nan + given y = forward(-100.0) + then y >= 0.0 and y < 0.000001 diff --git a/apps/website/public/widgets/nn-sigmoid/nn-sigmoid.t27 b/apps/website/public/widgets/nn-sigmoid/nn-sigmoid.t27 new file mode 100644 index 0000000000..f88b67dbf7 --- /dev/null +++ b/apps/website/public/widgets/nn-sigmoid/nn-sigmoid.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-sigmoid.t27 -- the sigmoid: any number into a probability +; Source of truth for public/widgets/nn-sigmoid/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-sigmoid/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/sigmoid_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 2 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -8 to 8. The curve is forward and the slope derivative of +; the spec, which takes the OUTPUT of the sigmoid, as backpropagation does; the tiles read the slope +; at x, at 0 and at the far right. + +; WHAT IT DOES NOT CLAIM: the slope bound of 0.25 is read off the compiled curve at x = 0, not +; proved here. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_sigmoid; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-sigmoid"; +pub const TITLE : str = "Sigmoid: turn any number into a probability"; +pub const DESCRIPTION : str = "Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends."; +pub const IMAGE_ALT : str = "Sigmoid card at x = 2: the green S-curve from 0 to 1 over -8..8, the dashed gold slope a bump peaking at 0.25 at x = 0. Tiles read sigmoid 0.8808, slope 0.1050, slope at 0 = 0.2500 and slope at 8 = 0.000335; two bars repeat the output and the slope."; +pub const HOOK : str = "1 / (1 + e^-x) squeezes the whole line into 0..1. Its slope is never above 0.25, which is why deep sigmoid nets learned slowly."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/sigmoid_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 2 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -800; +pub const K_X_HI_C : i16 = 800; +pub const K_X_STEP_C : u8 = 10; +pub const K_X_TICKS : [5]i8 = [-8, -4, 0, 4, 8]; +pub const K_Y_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_X_C : [4]i16 = [200, 0, -400, 600]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["x = 2", "x = 0", "x = -4", "x = 6"]; +pub const SAY_ASK : str = "How does a neuron turn any number into a probability?"; +pub const SAY_X : str = "input x"; +pub const SAY_F : str = "sigmoid(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_PLOT_LABEL : str = "The sigmoid of x and its slope from -8 to 8, with a cursor you drag"; +pub const SAY_BARS_LABEL : str = "The output and the slope at x as bars from 0 to 1"; +pub const SAY_OUT : str = "probability"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_AT_ZERO : str = "slope at 0"; +pub const SAY_FAR : str = "slope at 8"; +pub const SAY_NOTE : str = "The slope is s (1 - s), computed from the output s itself. Far from 0 it is close to nothing, so a saturated sigmoid passes almost no gradient back."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/sigmoid_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_range_is_symmetric { + assert K_X_LO_C + K_X_HI_C == 0; + assert K_X_HI_C == 800; +} + +test the_axis_spans_zero_to_one { + assert K_Y_TICKS_C[0] == 0; + assert K_Y_TICKS_C[4] == 100; + assert K_PRESET_X_C[1] == 0; +} diff --git a/apps/website/public/widgets/nn-sigmoid/tool.js b/apps/website/public/widgets/nn-sigmoid/tool.js new file mode 100644 index 0000000000..999f4a3ff7 --- /dev/null +++ b/apps/website/public/widgets/nn-sigmoid/tool.js @@ -0,0 +1,36 @@ +// nn-sigmoid/tool.js -- lesson 2 of neural-networks: how a neuron turns any number into a +// probability. The curve, its slope and every tile are forward and derivative of gHashTag/t27 +// specs/ml/activation/sigmoid_activation.t27, compiled to wasm (./logic.js); the slope is computed +// from the output, as the spec does. Words are SAY_ and numbers K_ constants of specs/widgets/nn-sigmoid.t27. +import { derivative, forward } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -800)), X1 = centi(K('K_X_HI_C', 800)) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 10)), fmt: (v) => fmt(v, 1) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const bar = canvas('nn-bars', say('SAY_BARS_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_F'), COLORS[0]], [say('SAY_DF'), COLORS[1], true]]), bar, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 320, x0: X0, x1: X1, y0: 0, y1: 1, xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS_C', []).map(centi), xlabel: say('SAY_X') } + const p = plot(svg, o) + p.line(sample((x) => forward(x), X0, X1), COLORS[0], 3) + p.line(sample((x) => derivative(forward(x)), X0, X1), COLORS[1], 2, { 'stroke-dasharray': '6 5' }) + const y = forward(s.x) + cursor(svg, p, s.x, [[y, COLORS[0]], [derivative(y), COLORS[1]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + bars(bar, { values: [y, derivative(y)], labels: [say('SAY_F'), say('SAY_DF')], colors: [COLORS[0], COLORS[1]], lo: 0, hi: 1, h: 200, ticks: K('K_Y_TICKS_C', []).map(centi), fmt: (v) => fmt(v, 4) }) + stat.replaceChildren(tiles([ + { label: say('SAY_OUT'), value: fmt(y, 4), tone: 0 }, + { label: say('SAY_GRAD'), value: fmt(derivative(y), 4), tone: 1 }, + { label: say('SAY_AT_ZERO'), value: fmt(derivative(forward(0)), 4), tone: 2 }, + { label: say('SAY_FAR'), value: fmt(derivative(forward(X1)), 6), tone: 6 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-silu/card.png b/apps/website/public/widgets/nn-silu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..065dfe534e41b4bdf72129ee32d30dac2561c6b1 GIT binary patch literal 49261 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-silu/index.html b/apps/website/public/widgets/nn-silu/index.html new file mode 100644 index 0000000000..8b5b74410c --- /dev/null +++ b/apps/website/public/widgets/nn-silu/index.html @@ -0,0 +1,47 @@ + + + + + + +Swish: one knob between a smooth curve and ReLU · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Swish: one knob between a smooth curve and ReLU

+

Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/silu_swish_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 5 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-silu/logic.js b/apps/website/public/widgets/nn-silu/logic.js new file mode 100644 index 0000000000..205aa9b157 --- /dev/null +++ b/apps/website/public/widgets/nn-silu/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from silu_swish_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 407115e99a8dd8f07ec28f899ef3336b0b9106ce30581cb0a3ed4217f5962364 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-silu/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABHgVgAAF9YAR9fX1/AX1gAn19AX1gAX0BfWACfX8BfQMIBwABAgIDAwQEBQFwAQEBBQMBABEGCQF/AUGAgMAACwdYBgZtZW1vcnkCAA90MjdfdmFsaWRfaW5wdXQAAAx0MjdfYmF0Y2hfYXQAAQ50MjdfZGVyaXZhdGl2ZQACC3QyN19mb3J3YXJkAAMLdDI3X3NpZ21vaWQABAr6BgcHAEMAAABAC40BAQN/I4CAgIAAQRBrIgQkgICAgAAgBCACOAIMIAQgATgCCCAEIAA4AgRBACEFAkADQCAFQQxGDQEgBEEEaiAFaiIGKgIAIQIgBiACQwAAgD8gAowQhYCAgABDAACAP5KVlDgCACAFQQRqIQUMAAsLIARBBGogA0ECdGoqAgAhAiAEQRBqJICAgIAAIAILLQBDAACAPyAAIAGUIgCMEIWAgIAAQwAAgD+SlSIBIAAgAZRDAACAPyABk5SSCx0AIABDAACAPyABIACMlBCFgICAAEMAAIA/kpWUCxcAQwAAgD8gAIwQhYCAgABDAACAP5KVC9QCAgN/A30CQAJAIAAgAFwNACAAvCIBQR92IQICQAJAAkACQAJAAkACQCABQf////8HcSIDQc/YupUESw0AIANBmOTF9QNNDQEgA0GSq5T8A00NAgwECyADQYCAgPwHSw0GAkAgAUEASA0AIANBmOTFlQRJDQAgAEMAAAB/lA8LIAFBf0oNA0MAAAAAIQQgA0G047+WBEsNBwwDCyADQYCAgMgDTQ0BQQAhA0MAAAAAIQUgACEEDAQLIAJBAXMgAmshAwwCCyAAQwAAgD+SDwsgAEM7qrg/lCACQQJ0KgKAgMCAAJL8ACEDCyAAIAOyIgRDAHIxv5SSIgAgBEOOvr81lCIFkyEECyAAIAQgBCAEIASUIgYgBkMVUjW7lEOPqio+kpSTIgaUQwAAAEAgBpOVIAWTkkMAAIA/kiEEIANFDQEgBCADEIaAgIAADwsgACEECyAEC6YCAQR/AkACQCAAIABcDQAgALwiAkH/////B3FBgICA/AdPDQAgAkGAgICAeHEhA0EIIAJBAXQiBGdrIARBGHYgBEGAgIAISRshBAJAIAFBAEgNAAJAIAFB/gEgBGtMDQBDAACAfyAAmA8LAkAgBCABaiIFQQBKDQAgAiABdCADcr4PCwJAIARBAEoNACACQQEgBGt0Qf///wNxIAVBF3RyIANyvg8LIAFBF3QgAmq+DwsgAUEAIARrSg0BAkAgAUFpIARrTg0AIAO+DwtBgICABEEAIARBAEobIAJB////A3FyQQAgAWsiA0EBIAEgBGprIgEgAyABSBtBf2oiAXZBAWpBAXYgAmggAUEfcUZBf3NxviAAmCEACyAADwsgAUEXdCACar4LCxEBAEGAgMAACwgAAAA/AAAAvw=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function sigmoid(z) { + return W.t27_sigmoid(z); +} +function forward(x, beta) { + return W.t27_forward(x, beta); +} +function derivative(x, beta) { + return W.t27_derivative(x, beta); +} +function batchAt(a, b, c, index) { + return W.t27_batch_at(a, b, c, int(index, 0, 4294967295, "batch_at.index")); +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["forward_batch"]); +export { + __NOT_LOWERED__, + batchAt, + derivative, + forward, + sigmoid, + validInput +}; diff --git a/apps/website/public/widgets/nn-silu/logic.t27 b/apps/website/public/widgets/nn-silu/logic.t27 new file mode 100644 index 0000000000..404271397f --- /dev/null +++ b/apps/website/public/widgets/nn-silu/logic.t27 @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// SiLU derivative | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward_batch returned its input unchanged, beta was never read, and the +// invariants asserted `true` over an undeclared `valid_input`. SiLU is now +// x * sigmoid(beta * x) (Swish; beta = 1 is SiLU) on scalars and in place on slices. + +module SiluSwish; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const DEFAULT_BETA : f32 = 1.0; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const SiLUConfig = struct { + beta : f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // sigmoid(z) = 1 / (1 + exp(-z)) + fn sigmoid(z: f32) -> f32 { + return 1.0 / (1.0 + exp(-z)); + } + + // Swish(x) = x * sigmoid(beta * x); beta = 1 is SiLU + fn forward(x: f32, beta: f32) -> f32 { + return x * sigmoid(beta * x); + } + + // forward on each element IN PLACE; returns the same slice + fn forward_batch(input: []f32, beta: f32) -> []f32 { + var i : usize = 0; + while (i < input.len) { + input[i] = forward(input[i], beta); + i = i + 1; + } + return input; + } + + // d/dx x sigmoid(beta x) = s + beta x s (1 - s), s = sigmoid(beta x) + fn derivative(x: f32, beta: f32) -> f32 { + const s = sigmoid(beta * x); + return s + beta * x * s * (1.0 - s); + } + + fn batch_at(a: f32, b: f32, c: f32, index: usize) -> f32 { + var input : [3]f32 = [a, b, c]; + const output = forward_batch(&input, DEFAULT_BETA); + return output[index]; + } + + fn valid_input() -> f32 { + return 2.0; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + test "forward_basic_case" + given input = 0.0, beta = 1.0 + when result = forward(input, beta) + then result == 0.0 // SiLU(0) = 0 * sigmoid(0) = 0 + + test "forward_positive_case" + given input = 1.0, beta = 1.0 + when result = forward(input, beta) + then result > 0.0 // SiLU(1) = 1 * sigmoid(1) > 0 + + test "forward_negative_case" + given input = -1.0, beta = 1.0 + when result = forward(input, beta) + then result < 0.0 // SiLU(-1) = -1 * sigmoid(-1) < 0 + + test "forward_batch_basic_case" + given beta = 1.0 + when result = batch_at(1.0, 2.0, 3.0, 2) + then @abs(result - forward(3.0, beta)) < 0.0000001 and @abs(batch_at(1.0, 2.0, 3.0, 0) - 0.7310586) < 0.000001 + + test "forward_batch_zero_case" + given beta = 1.0 + when result = batch_at(0.0, 0.0, 0.0, 0) + then result == 0.0 and batch_at(0.0, 0.0, 0.0, 1) == 0.0 and batch_at(0.0, 0.0, 0.0, 2) == 0.0 // SiLU(0) = 0 + + test "derivative_basic_case" + given input = 0.0, beta = 1.0 + when result = derivative(input, beta) + then result > 0.0 // SiLU'(0) = sigmoid(0) + 0 * sigmoid(0) * (1 - sigmoid(0)) = sigmoid(0) > 0 + + test "derivative_positive_case" + given input = 1.0, beta = 1.0 + when result = derivative(input, beta) + then result > 0.0 // SiLU derivative should be positive for positive inputs + + test "derivative_negative_case" + given input = -1.0, beta = 1.0 + when result = derivative(input, beta) + then result > 0.0 // SiLU derivative should be positive for negative inputs too + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // beta > 0 + invariant silu_swish_constraint_0 + assert DEFAULT_BETA > 0.0 + + // name: silu_formula -- x * sigmoid(x), so SiLU(x) - SiLU(-x) = x + invariant silu_swish_constraint_1 + assert @abs(forward(valid_input(), DEFAULT_BETA) - forward(-valid_input(), DEFAULT_BETA) - valid_input()) < 0.000001 + + // name: derivative -- sigmoid(0) = 0.5 at the origin + invariant silu_swish_constraint_2 + assert derivative(0.0, DEFAULT_BETA) == 0.5 + + // "Elfwing et al. (2017) - Sigmoid-Weighted Linear Units for Neural Network Function Approximation": + // SiLU dips below zero left of the origin + invariant silu_swish_constraint_3 + assert forward(-valid_input(), DEFAULT_BETA) < 0.0 + + // "Ramachandran et al. (2017) - Searching for Activation Functions (Swish)": a large beta + // approaches ReLU + invariant silu_swish_constraint_4 + assert @abs(forward(valid_input(), 50.0) - valid_input()) < 0.000001 diff --git a/apps/website/public/widgets/nn-silu/nn-silu.t27 b/apps/website/public/widgets/nn-silu/nn-silu.t27 new file mode 100644 index 0000000000..087ee92a09 --- /dev/null +++ b/apps/website/public/widgets/nn-silu/nn-silu.t27 @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-silu.t27 -- Swish and SiLU: one knob between a smooth curve and ReLU +; Source of truth for public/widgets/nn-silu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-silu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/silu_swish_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 5 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -5 to 5 and sets beta from 0.25 to 8. The green curve is +; forward(x, beta), the dotted one forward(x, 1), SiLU, and the dashed one derivative(x, beta). + +; WHAT IT DOES NOT CLAIM: the claim that large beta approaches ReLU is what the curves show on this +; window, not a limit taken here. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_silu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-silu"; +pub const TITLE : str = "Swish: one knob between a smooth curve and ReLU"; +pub const DESCRIPTION : str = "Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2."; +pub const IMAGE_ALT : str = "Swish card at beta 1, x = -1.28: the green curve dips to -0.2785 and then rises along the diagonal, over a dotted violet SiLU reference that matches it; the dashed gold slope crosses zero at the cursor. Tiles read output -0.2785, slope -0.0003, SiLU -0.2785 and the spec batch (-2, 0, 2) as -0.238 0.000 1.762."; +pub const HOOK : str = "SiLU(-1.28) = -0.2785, its lowest point. At beta 8 the dip shrinks to almost nothing and the curve is ReLU with rounded corners."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/silu_swish_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 5 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -500; +pub const K_X_HI_C : i16 = 500; +pub const K_X_STEP_C : u8 = 2; +pub const K_Y_LO_C : i16 = -100; +pub const K_Y_HI_C : i16 = 500; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [7]i8 = [-1, 0, 1, 2, 3, 4, 5]; +pub const K_BETA_LO_C : u8 = 25; +pub const K_BETA_HI_C : u16 = 800; +pub const K_BETA_STEP_C : u8 = 25; +pub const K_FIXTURE_C : [3]i16 = [-200, 0, 200]; +pub const K_PRESET_X_C : [4]i16 = [-128, -128, 200, 200]; +pub const K_PRESET_BETA_C : [4]u16 = [100, 400, 50, 800]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["SiLU at its dip", "beta 4 at the same x", "beta 0.5 at x = 2", "beta 8 at x = 2"]; +pub const SAY_ASK : str = "Is there one knob between a smooth curve and ReLU?"; +pub const SAY_X : str = "input x"; +pub const SAY_BETA : str = "beta"; +pub const SAY_F : str = "x sigmoid(beta x)"; +pub const SAY_SILU : str = "SiLU, beta 1"; +pub const SAY_DF : str = "slope"; +pub const SAY_PLOT_LABEL : str = "Swish of x for the chosen beta, SiLU for reference, and the slope"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_SILU_AT : str = "SiLU at x"; +pub const SAY_BATCH : str = "spec batch -2 0 2"; +pub const SAY_NOTE : str = "Swish multiplies x by a sigmoid gate of itself. beta sets how sharp the gate is: the same unit can be gentle or close to a switch."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/silu_swish_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test beta_one_is_silu { + assert K_PRESET_BETA_C[0] == 100; + assert K_BETA_LO_C < K_PRESET_BETA_C[0]; + assert K_PRESET_BETA_C[3] == K_BETA_HI_C; +} + +test the_presets_stay_in_range { + assert K_PRESET_X_C[0] >= K_X_LO_C; + assert K_PRESET_X_C[3] <= K_X_HI_C; + assert K_BETA_HI_C % K_BETA_STEP_C == 0; +} diff --git a/apps/website/public/widgets/nn-silu/tool.js b/apps/website/public/widgets/nn-silu/tool.js new file mode 100644 index 0000000000..a6a7944f19 --- /dev/null +++ b/apps/website/public/widgets/nn-silu/tool.js @@ -0,0 +1,37 @@ +// nn-silu/tool.js -- lesson 5 of neural-networks: one knob between a smooth curve and ReLU. Swish is +// x times sigmoid(beta x): at beta 1 it is SiLU, and as beta grows it closes on ReLU. Both curves +// and every tile are forward and derivative of gHashTag/t27 specs/ml/activation/ +// silu_swish_activation.t27, compiled to wasm (./logic.js). Words are SAY_ and numbers K_ constants +// of specs/widgets/nn-silu.t27. +import { batchAt, derivative, forward } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -500)), X1 = centi(K('K_X_HI_C', 500)) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 2)), fmt: (v) => fmt(v, 2) }, + { key: 'beta', label: say('SAY_BETA'), min: centi(K('K_BETA_LO_C', 25)), max: centi(K('K_BETA_HI_C', 800)), step: centi(K('K_BETA_STEP_C', 25)), fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi), beta: K('K_PRESET_BETA_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_F'), COLORS[0]], [say('SAY_SILU'), COLORS[5], true], [say('SAY_DF'), COLORS[1], true]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 340, x0: X0, x1: X1, y0: centi(K('K_Y_LO_C', -100)), y1: centi(K('K_Y_HI_C', 500)), xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_X') } + const p = plot(svg, o) + p.line(sample((x) => forward(x, 1), X0, X1), COLORS[5], 1.5, { 'stroke-dasharray': '4 5' }) + p.line(sample((x) => derivative(x, s.beta), X0, X1), COLORS[1], 2, { 'stroke-dasharray': '6 5' }) + p.line(sample((x) => forward(x, s.beta), X0, X1), COLORS[0], 3.5) + cursor(svg, p, s.x, [[forward(s.x, s.beta), COLORS[0]], [derivative(s.x, s.beta), COLORS[1]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + const fx = K('K_FIXTURE_C', []).map(centi) + stat.replaceChildren(tiles([ + { label: say('SAY_OUT'), value: fmt(forward(s.x, s.beta), 4), tone: 0 }, + { label: say('SAY_GRAD'), value: fmt(derivative(s.x, s.beta), 4), tone: 1 }, + { label: say('SAY_SILU_AT'), value: fmt(forward(s.x, 1), 4), tone: 5 }, + { label: say('SAY_BATCH'), value: [0, 1, 2].map((i) => fmt(batchAt(fx[0], fx[1], fx[2], i), 3)).join(' '), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-softmax/card.png b/apps/website/public/widgets/nn-softmax/card.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1e8f7151ef82cef001458f7499f08a4fbaed79 GIT binary patch literal 44030 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 *iLT%4V<#t%Z{IW={kHZM|4OOMnn8Mr!P3v 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 T0B5L600000NkvXXu0mjf;!WWz literal 0 HcmV?d00001 diff --git a/apps/website/public/widgets/nn-softmax/index.html b/apps/website/public/widgets/nn-softmax/index.html new file mode 100644 index 0000000000..3a67c1c163 --- /dev/null +++ b/apps/website/public/widgets/nn-softmax/index.html @@ -0,0 +1,47 @@ + + + + + + +Softmax: how a network turns scores into a choice · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

Softmax: how a network turns scores into a choice

+

Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/softmax.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 7 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-softmax/logic.js b/apps/website/public/widgets/nn-softmax/logic.js new file mode 100644 index 0000000000..969a633d49 --- /dev/null +++ b/apps/website/public/widgets/nn-softmax/logic.js @@ -0,0 +1,40 @@ +// Generated by scripts/t27-logic.mjs from softmax.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 7466b7f756ea132c84d11d53f7f71ca4a66aca69ca98feb2a58ff204157baa78 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-softmax/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABMwhgAAF9YAR9fX1/AX1gA39/fwBgA319fQF9YAV9fX19fwF9YAF/AX1gAX0BfWACfX8BfQMLCgABAgIDBAUEBgcEBQFwAQEBBQMBABEGCQF/AUGAgMAACwdcBgZtZW1vcnkCAA90MjdfdmFsaWRfaW5wdXQAAAt0MjdfZ3JhZF9hdAABDHQyN193ZWlnaHRlZAAED3QyN19iYWNrd2FyZF9hdAAGDnQyN19zb2Z0bWF4X2F0AAcK7wsKBwBDAABAQAvOAQEBfyOAgICAAEHQAGsiBCSAgICAACAEQQhqQQhqQQA2AgAgBCACOAIgIAQgATgCHCAEIAA4AhggBEIANwMIIARCgICA/AM3AiQgBEEBOgAsIARBAToAQCAEQRhqIARBCGogBEEkahCCgICAACAEQTBqQQhqQQA2AgAgBEIANwMwIARCgICA/AM3AkAgBEEBOgBIIARBAToATCAEQQhqIARBMGogBEHAAGoQg4CAgAAgBEEwaiADQQJ0aioCACECIARB0ABqJICAgIAAIAILswEBBH0gACoCACEDIAIqAgAhBEEAIQIDQAJAIAJBDEcNAEMAAAAAIQVBACECA0ACQCACQQxHDQBBACECAkADQCACQQxGDQEgASACaiIAIAAqAgAgBZU4AgAgAkEEaiECDAALCw8LIAEgAmogACACaioCACADkyAElRCIgICAACIGOAIAIAJBBGohAiAFIAaSIQUMAAsLIAAgAmoqAgAiBSADIAUgA14bIQMgAkEEaiECDAALC4QBAQJ9IAIqAgAhA0MAAAAAIQRBACECA0ACQCACQQxHDQBBACECAkADQCACQQxGDQEgASACaiAAIAJqKgIAIAJBgIDAgABqKgIAIASTlCADlTgCACACQQRqIQIMAAsLDwsgBCACQYCAwIAAaioCACAAIAJqKgIAlJIhBCACQQRqIQIMAAsLTwAgACABIAJDAACAP0EAEIWAgIAAQ83MzD2UIAAgASACQwAAgD9BARCFgICAAEPNzEw+lJIgACABIAJDAACAP0ECEIWAgIAAQ5qZmT6UkguJAQEBfyOAgICAAEEwayIFJICAgIAAIAVBGGpBADYCACAFIAI4AgwgBSABOAIIIAUgADgCBCAFQgA3AxAgBUEANgIkIAUgAzgCICAFQQE6ACggBUEBOgAsIAVBBGogBUEQaiAFQSBqEIKAgIAAIAVBEGogBEECdGoqAgAhAiAFQTBqJICAgIAAIAILbgIBfwF9I4CAgIAAQSBrIgEkgICAgAAgAUEIakEANgIAIAFCADcDACABQoCAgPwDNwIQIAFBAToAGCABQQE6ABxBjIDAgAAgASABQRBqEIOAgIAAIAEgAEECdGoqAgAhAiABQSBqJICAgIAAIAILEgAgACABIAIgAyAEEIWAgIAAC9QCAgN/A30CQAJAIAAgAFwNACAAvCIBQR92IQICQAJAAkACQAJAAkACQCABQf////8HcSIDQc/YupUESw0AIANBmOTF9QNNDQEgA0GSq5T8A00NAgwECyADQYCAgPwHSw0GAkAgAUEASA0AIANBmOTFlQRJDQAgAEMAAAB/lA8LIAFBf0oNA0MAAAAAIQQgA0G047+WBEsNBwwDCyADQYCAgMgDTQ0BQQAhA0MAAAAAIQUgACEEDAQLIAJBAXMgAmshAwwCCyAAQwAAgD+SDwsgAEM7qrg/lCACQQJ0KgKYgMCAAJL8ACEDCyAAIAOyIgRDAHIxv5SSIgAgBEOOvr81lCIFkyEECyAAIAQgBCAEIASUIgYgBkMVUjW7lEOPqio+kpSTIgaUQwAAAEAgBpOVIAWTkkMAAIA/kiEEIANFDQEgBCADEImAgIAADwsgACEECyAEC6YCAQR/AkACQCAAIABcDQAgALwiAkH/////B3FBgICA/AdPDQAgAkGAgICAeHEhA0EIIAJBAXQiBGdrIARBGHYgBEGAgIAISRshBAJAIAFBAEgNAAJAIAFB/gEgBGtMDQBDAACAfyAAmA8LAkAgBCABaiIFQQBKDQAgAiABdCADcr4PCwJAIARBAEoNACACQQEgBGt0Qf///wNxIAVBF3RyIANyvg8LIAFBF3QgAmq+DwsgAUEAIARrSg0BAkAgAUFpIARrTg0AIAO+DwtBgICABEEAIARBAEobIAJB////A3FyQQAgAWsiA0EBIAEgBGprIgEgAyABSBtBf2oiAXZBAWpBAXYgAmggAUEfcUZBf3NxviAAmCEACyAADwsgAUEXdCACar4LCykBAEGAgMAACyDNzMw9zcxMPpqZmT7NzEw+mpmZPgAAAD8AAAA/AAAAvw=="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function softmaxAt(a, b, c, temperature, index) { + return W.t27_softmax_at(a, b, c, temperature, int(index, 0, 4294967295, "softmax_at.index")); +} +function backwardAt(index) { + return W.t27_backward_at(int(index, 0, 4294967295, "backward_at.index")); +} +function weighted(a, b, c) { + return W.t27_weighted(a, b, c); +} +function gradAt(a, b, c, index) { + return W.t27_grad_at(a, b, c, int(index, 0, 4294967295, "grad_at.index")); +} +function validInput() { + return W.t27_valid_input(); +} +const __NOT_LOWERED__ = Object.freeze(["forward", "backward", "cfg"]); +export { + __NOT_LOWERED__, + backwardAt, + gradAt, + softmaxAt, + validInput, + weighted +}; diff --git a/apps/website/public/widgets/nn-softmax/logic.t27 b/apps/website/public/widgets/nn-softmax/logic.t27 new file mode 100644 index 0000000000..859f9db7ed --- /dev/null +++ b/apps/website/public/widgets/nn-softmax/logic.t27 @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Control sharpness of distribution | φ² + 1/φ² = 3 | TRINITY + +// #8980: written with `range` and `math::exp`, which no spec declares, so no test +// ever ran. backward was also wrong: it used only the Jacobian's diagonal, +// p_i (1 - p_i), and dropped the -p_i p_j terms. It is now the full product +// grad_input_i = p_i (g_i - sum_j g_j p_j) / temperature. + +module Softmax; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const ZERO : f32 = 0.0; + const ONE : f32 = 1.0; + const MIN_TEMP : f32 = 0.001; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const SoftmaxConfig = struct { + temperature : f32, + axis : u32, + stable : bool, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // output_i = exp((x_i - max) / T) / sum_j exp((x_j - max) / T); subtracting the max keeps exp finite + fn forward(logits: []const f32, output: []f32, config: SoftmaxConfig) -> void { + var max_val : f32 = logits[0]; + var i : usize = 0; + while (i < logits.len) { + if (logits[i] > max_val) { + max_val = logits[i]; + } + i = i + 1; + } + var sum : f32 = ZERO; + i = 0; + while (i < logits.len) { + output[i] = exp((logits[i] - max_val) / config.temperature); + sum = sum + output[i]; + i = i + 1; + } + i = 0; + while (i < logits.len) { + output[i] = output[i] / sum; + i = i + 1; + } + } + + // Vector-Jacobian product: grad_input_i = p_i (g_i - sum_j g_j p_j) / T + fn backward(grad_output: []const f32, probabilities: []const f32, grad_input: []f32, config: SoftmaxConfig) -> void { + var dot : f32 = ZERO; + var i : usize = 0; + while (i < grad_output.len) { + dot = dot + grad_output[i] * probabilities[i]; + i = i + 1; + } + i = 0; + while (i < grad_output.len) { + grad_input[i] = probabilities[i] * (grad_output[i] - dot) / config.temperature; + i = i + 1; + } + } + + fn cfg(temperature: f32) -> SoftmaxConfig { + return SoftmaxConfig{ .temperature = temperature, .axis = 0, .stable = true }; + } + + // output[index] of softmax over (a, b, c) + fn softmax_at(a: f32, b: f32, c: f32, temperature: f32, index: usize) -> f32 { + const logits : [3]f32 = [a, b, c]; + var output : [3]f32 = [0.0] ** 3; + forward(&logits, &output, cfg(temperature)); + return output[index]; + } + + // grad_input[index] for grad_output (0.1, 0.2, 0.3) at probabilities (0.2, 0.3, 0.5) + fn backward_at(index: usize) -> f32 { + const grad_output : [3]f32 = [0.1, 0.2, 0.3]; + const probabilities : [3]f32 = [0.2, 0.3, 0.5]; + var grad_input : [3]f32 = [0.0] ** 3; + backward(&grad_output, &probabilities, &grad_input, cfg(1.0)); + return grad_input[index]; + } + + // L = sum_i w_i softmax(x)_i with w = (0.1, 0.2, 0.3): the loss whose gradient backward computes + fn weighted(a: f32, b: f32, c: f32) -> f32 { + return 0.1 * softmax_at(a, b, c, 1.0, 0) + 0.2 * softmax_at(a, b, c, 1.0, 1) + 0.3 * softmax_at(a, b, c, 1.0, 2); + } + + fn grad_at(a: f32, b: f32, c: f32, index: usize) -> f32 { + const grad_output : [3]f32 = [0.1, 0.2, 0.3]; + var probabilities : [3]f32 = [0.0] ** 3; + const logits : [3]f32 = [a, b, c]; + forward(&logits, &probabilities, cfg(1.0)); + var grad_input : [3]f32 = [0.0] ** 3; + backward(&grad_output, &probabilities, &grad_input, cfg(1.0)); + return grad_input[index]; + } + + fn valid_input() -> f32 { + return 3.0; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // softmax(1, 2, 3) = (0.0900306, 0.2447285, 0.6652410) + test "forward_basic_case" + given p0 = softmax_at(1.0, 2.0, 3.0, 1.0, 0) + when p2 = softmax_at(1.0, 2.0, 3.0, 1.0, 2) + then p0 > 0.0 and softmax_at(1.0, 2.0, 3.0, 1.0, 1) > 0.0 and p2 > 0.0 and @abs(p0 + softmax_at(1.0, 2.0, 3.0, 1.0, 1) + p2 - 1.0) < 0.0001 and @abs(p0 - 0.0900306) < 0.000001 and @abs(p2 - 0.6652410) < 0.000001 + + // Subtracting the max: logits of 1000 do not overflow exp + test "forward_large_logits_stay_finite" + given p = softmax_at(1000.0, 1000.0, 1000.0, 1.0, 1) + then @abs(p - 1.0 / 3.0) < 0.000001 + + // A higher temperature flattens the distribution toward uniform + test "forward_temperature_flattens" + given sharp = softmax_at(1.0, 2.0, 3.0, 1.0, 2) + when flat = softmax_at(1.0, 2.0, 3.0, 10.0, 2) + then flat < sharp and flat > 1.0 / 3.0 + + // dot = 0.23: grad = (0.2 (0.1 - 0.23), 0.3 (0.2 - 0.23), 0.5 (0.3 - 0.23)) = (-0.026, -0.009, 0.035) + test "backward_basic_case" + given g0 = backward_at(0) + when g2 = backward_at(2) + then g0 != 0.0 and backward_at(1) != 0.0 and g2 != 0.0 and @abs(g0 - (-0.026)) < 0.000001 and @abs(backward_at(1) - (-0.009)) < 0.000001 and @abs(g2 - 0.035) < 0.000001 + + // The gradient of a function of probabilities that sum to 1 sums to 0 + test "backward_sums_to_zero" + given total = backward_at(0) + backward_at(1) + backward_at(2) + then @abs(total) < 0.0000001 + + test "backward_matches_finite_difference" + given slope = (weighted(1.0, 2.0 + 0.001, 3.0) - weighted(1.0, 2.0 - 0.001, 3.0)) / 0.002 + when result = grad_at(1.0, 2.0, 3.0, 1) + then @abs(result - slope) < 0.0005 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // logits.size() == output.size(): the first and last element are both probabilities + invariant softmax_constraint_0 + assert softmax_at(1.0, 2.0, valid_input(), 1.0, 0) >= 0.0 and softmax_at(1.0, 2.0, valid_input(), 1.0, 2) >= 0.0 + + // config.temperature >= MIN_TEMP + invariant softmax_constraint_1 + assert cfg(1.0).temperature >= MIN_TEMP + + // sum(output) = 1.0 within floating precision + invariant softmax_constraint_2 + assert @abs(softmax_at(1.0, 2.0, valid_input(), 1.0, 0) + softmax_at(1.0, 2.0, valid_input(), 1.0, 1) + softmax_at(1.0, 2.0, valid_input(), 1.0, 2) - 1.0) < 0.0001 diff --git a/apps/website/public/widgets/nn-softmax/nn-softmax.t27 b/apps/website/public/widgets/nn-softmax/nn-softmax.t27 new file mode 100644 index 0000000000..09d52e7cde --- /dev/null +++ b/apps/website/public/widgets/nn-softmax/nn-softmax.t27 @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-softmax.t27 -- softmax and temperature: scores into a choice +; Source of truth for public/widgets/nn-softmax/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-softmax/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/softmax.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 7 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets three scores from -3 to 3 and a temperature from 0.1 to 5. The bars +; are softmax_at(a, b, c, T, i) and the sweep draws the same fn over T, with a cursor to drag. + +; WHAT IT DOES NOT CLAIM: three scores stand for a layer of any width; the spec's softmax_at takes +; three. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_softmax; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-softmax"; +pub const TITLE : str = "Softmax: how a network turns scores into a choice"; +pub const DESCRIPTION : str = "Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out."; +pub const IMAGE_ALT : str = "Softmax card: scores 1, 2 and 3 at temperature 1. Three bars in cyan, pink and green stand at 0.0900, 0.2447 and 0.6652. Below, three curves sweep the temperature from 0.1 to 5: the green one falls from 1 toward 0.4 while the other two rise, with a cursor at T = 1."; +pub const HOOK : str = "Scores 1, 2, 3 give 0.090, 0.245, 0.665. At temperature 0.5 the top one takes 0.867; at 5 the three are 0.27, 0.33, 0.40."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/softmax.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 7 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SCORE_LO_C : i16 = -300; +pub const K_SCORE_HI_C : i16 = 300; +pub const K_T_LO_C : u8 = 10; +pub const K_T_HI_C : u16 = 500; +pub const K_T_STEP_C : u8 = 5; +pub const K_T_TICKS : [6]u8 = [0, 1, 2, 3, 4, 5]; +pub const K_P_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_A_C : [4]i16 = [100, 100, 100, 200]; +pub const K_PRESET_B_C : [4]i16 = [200, 200, 200, 200]; +pub const K_PRESET_C_C : [4]i16 = [300, 300, 300, 0]; +pub const K_PRESET_T_C : [4]u16 = [100, 50, 500, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["1, 2, 3 at T = 1", "1, 2, 3 at T = 0.5", "1, 2, 3 at T = 5", "A tie: 2, 2, 0"]; +pub const SAY_ASK : str = "How does a network turn scores into a choice?"; +pub const SAY_A : str = "A"; +pub const SAY_B : str = "B"; +pub const SAY_C : str = "C"; +pub const SAY_T : str = "temperature T"; +pub const SAY_BARS_LABEL : str = "The three probabilities softmax gives the three scores"; +pub const SAY_SWEEP_LABEL : str = "Each probability as the temperature goes from 0.1 to 5"; +pub const SAY_SWEEP : str = "Drag along the temperature: the same three scores, cooled and heated."; +pub const SAY_P : str = "p({0})"; +pub const SAY_COLD : str = "at T = {0}"; +pub const SAY_NOTE : str = "Softmax is exp(x / T) over the sum of all of them, with the largest score subtracted first so exp never overflows. A language model samples its next token from exactly this."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/softmax.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_temperature_stays_positive { + assert K_T_LO_C > 0; + assert K_T_HI_C == 500; + assert K_PRESET_T_C[1] < K_PRESET_T_C[0]; +} + +test the_presets_stay_in_range { + assert K_PRESET_C_C[0] == K_SCORE_HI_C; + assert K_PRESET_A_C[3] == K_PRESET_B_C[3]; + assert K_PRESET_T_C[2] == K_T_HI_C; +} diff --git a/apps/website/public/widgets/nn-softmax/tool.js b/apps/website/public/widgets/nn-softmax/tool.js new file mode 100644 index 0000000000..852840f5d9 --- /dev/null +++ b/apps/website/public/widgets/nn-softmax/tool.js @@ -0,0 +1,41 @@ +// nn-softmax/tool.js -- lesson 7 of neural-networks: how a network turns scores into a choice. +// Softmax makes three scores into three probabilities that sum to one, and the temperature decides +// how sure it is. Every bar and every point of the temperature sweep is softmax_at of gHashTag/t27 +// specs/ml/activation/softmax.t27, compiled to wasm (./logic.js). Words are SAY_ and numbers K_ +// constants of specs/widgets/nn-softmax.t27. +import { softmaxAt } from './logic.js' +import { COLORS, K, W, ask, bars, canvas, centi, controls, cursor, dragX, el, fill, fmt, legend, plot, root, sample, say, source, tiles } from '../nn-kit.js' + +const S0 = centi(K('K_SCORE_LO_C', -300)), S1 = centi(K('K_SCORE_HI_C', 300)) +const T0 = centi(K('K_T_LO_C', 10)), T1 = centi(K('K_T_HI_C', 500)) +const score = (key, label) => ({ key, label, min: S0, max: S1, step: 0.1, fmt: (v) => fmt(v, 1) }) +const ctl = controls([ + score('a', say('SAY_A')), score('b', say('SAY_B')), score('c', say('SAY_C')), + { key: 't', label: say('SAY_T'), min: T0, max: T1, step: centi(K('K_T_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { a: K('K_PRESET_A_C', []).map(centi), b: K('K_PRESET_B_C', []).map(centi), c: K('K_PRESET_C_C', []).map(centi), t: K('K_PRESET_T_C', []).map(centi) } }, draw) + +const chart = canvas('nn-bars', say('SAY_BARS_LABEL')) +const sweep = canvas('nn-curve', say('SAY_SWEEP_LABEL')) +const stat = el('div') +const names = [say('SAY_A'), say('SAY_B'), say('SAY_C')] +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, chart, stat, el('p', { class: 'dk-note' }, say('SAY_SWEEP')), sweep, legend(names.map((n, i) => [n, COLORS[[2, 3, 0][i]]])), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + const p3 = [0, 1, 2].map((i) => softmaxAt(s.a, s.b, s.c, s.t, i)) + const colors = [COLORS[2], COLORS[3], COLORS[0]] + bars(chart, { values: p3, labels: names.map((n, i) => `${n} = ${fmt([s.a, s.b, s.c][i], 1)}`), colors, lo: 0, hi: 1, h: 240, ticks: K('K_P_TICKS_C', []).map(centi), fmt: (v) => fmt(v, 4) }) + sweep.replaceChildren() + const o = { w: 640, h: 280, x0: T0, x1: T1, y0: 0, y1: 1, xticks: K('K_T_TICKS', []), yticks: K('K_P_TICKS_C', []).map(centi), xlabel: say('SAY_T') } + const p = plot(sweep, o) + for (let i = 0; i < 3; i++) p.line(sample((t) => softmaxAt(s.a, s.b, s.c, t, i), T0, T1, 120), colors[i], 3) + cursor(sweep, p, s.t, p3.map((v, i) => [v, colors[i]])) + dragX(sweep, p, o, (t) => ctl.set('t', t)) + stat.replaceChildren(tiles([ + { label: fill(say('SAY_P'), names[0]), value: fmt(p3[0], 4), tone: 2 }, + { label: fill(say('SAY_P'), names[1]), value: fmt(p3[1], 4), tone: 3 }, + { label: fill(say('SAY_P'), names[2]), value: fmt(p3[2], 4), tone: 0 }, + { label: fill(say('SAY_COLD'), fmt(T0, 2)), value: [0, 1, 2].map((i) => fmt(softmaxAt(s.a, s.b, s.c, T0, i), 3)).join(' '), tone: 1 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-tanh/card.png b/apps/website/public/widgets/nn-tanh/card.png new file mode 100644 index 0000000000000000000000000000000000000000..952cf89b66c57ed2a2ce181774e3f34ec737381a GIT binary patch literal 46081 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 + + + + + +tanh: where a neuron stops learning · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + +
+Trinity S³AI +

tanh: where a neuron stops learning

+

Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped.

+
+
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/activation/tanh_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 3 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-tanh/logic.js b/apps/website/public/widgets/nn-tanh/logic.js new file mode 100644 index 0000000000..b25c8855fe --- /dev/null +++ b/apps/website/public/widgets/nn-tanh/logic.js @@ -0,0 +1,36 @@ +// Generated by scripts/t27-logic.mjs from tanh_activation.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 389394efbb10c82af69f052a9e7b3a929f09f45a7976930c79aee2352da4cf31 +// Imported by scripts/widget-logic.mjs for public/widgets/nn-tanh/: types stripped, nothing else changed. +const WASM = "AGFzbQEAAAABEQNgAX8BfWABfQF9YAJ9fwF9AwgHAAEBAQEBAgQFAXABAQEFAwEAEQYJAX8BQYCAwAALB1UFBm1lbW9yeQIADHQyN19iYXRjaF9hdAAAGnQyN19kZXJpdmF0aXZlX2Zyb21fb3V0cHV0AAIOdDI3X2Rlcml2YXRpdmUAAwt0MjdfZm9yd2FyZAAECvMGB3YCAn8BfSOAgICAAEEQayIBJICAgIAAQQAhAiABQQhqQQA2AgAgAUIANwMAAkADQCACQQxGDQEgASACaiACQYCAwIAAaioCABCBgICAADgCACACQQRqIQIMAAsLIAEgAEECdGoqAgAhAyABQRBqJICAgIAAIAMLTQACQCAAQwAAAABdRQ0AQwAAgD8gACAAkhCFgICAACIAk4wgAEMAAIA/kpUPC0MAAIA/IABDAAAAwJQQhYCAgAAiAJMgAEMAAIA/kpULDQBDAACAPyAAIACUkwsVAEMAAIA/IAAQgYCAgAAiACAAlJMLCgAgABCBgICAAAvUAgIDfwN9AkACQCAAIABcDQAgALwiAUEfdiECAkACQAJAAkACQAJAAkAgAUH/////B3EiA0HP2LqVBEsNACADQZjkxfUDTQ0BIANBkquU/ANNDQIMBAsgA0GAgID8B0sNBgJAIAFBAEgNACADQZjkxZUESQ0AIABDAAAAf5QPCyABQX9KDQNDAAAAACEEIANBtOO/lgRLDQcMAwsgA0GAgIDIA00NAUEAIQNDAAAAACEFIAAhBAwECyACQQFzIAJrIQMMAgsgAEMAAIA/kg8LIABDO6q4P5QgAkECdCoCjIDAgACS/AAhAwsgACADsiIEQwByMb+UkiIAIARDjr6/NZQiBZMhBAsgACAEIAQgBCAElCIGIAZDFVI1u5RDj6oqPpKUkyIGlEMAAABAIAaTlSAFk5JDAACAP5IhBCADRQ0BIAQgAxCGgICAAA8LIAAhBAsgBAumAgEEfwJAAkAgACAAXA0AIAC8IgJB/////wdxQYCAgPwHTw0AIAJBgICAgHhxIQNBCCACQQF0IgRnayAEQRh2IARBgICACEkbIQQCQCABQQBIDQACQCABQf4BIARrTA0AQwAAgH8gAJgPCwJAIAQgAWoiBUEASg0AIAIgAXQgA3K+DwsCQCAEQQBKDQAgAkEBIARrdEH///8DcSAFQRd0ciADcr4PCyABQRd0IAJqvg8LIAFBACAEa0oNAQJAIAFBaSAEa04NACADvg8LQYCAgARBACAEQQBKGyACQf///wNxckEAIAFrIgNBASABIARqayIBIAMgAUgbQX9qIgF2QQFqQQF2IAJoIAFBH3FGQX9zcb4gAJghAAsgAA8LIAFBF3QgAmq+CwsdAQBBgIDAAAsUAAAAAAAAgD8AAABAAAAAPwAAAL8="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function forward(x) { + return W.t27_forward(x); +} +function derivative(x) { + return W.t27_derivative(x); +} +function derivativeFromOutput(tanhX) { + return W.t27_derivative_from_output(tanhX); +} +function batchAt(index) { + return W.t27_batch_at(int(index, 0, 4294967295, "batch_at.index")); +} +const __NOT_LOWERED__ = Object.freeze(["forward_batch"]); +export { + __NOT_LOWERED__, + batchAt, + derivative, + derivativeFromOutput, + forward +}; diff --git a/apps/website/public/widgets/nn-tanh/logic.t27 b/apps/website/public/widgets/nn-tanh/logic.t27 new file mode 100644 index 0000000000..b6044c349c --- /dev/null +++ b/apps/website/public/widgets/nn-tanh/logic.t27 @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// Derivative (can compute from output) | φ² + 1/φ² = 3 | TRINITY + +// #8980: `math::exp` named a module this spec never imports, and +// forward_batch allocated with `[]f32{input.len}`. tanh is now computed in the +// form that cannot overflow: exp(2|x|) reaches inf in f32 at |x| = 45, and +// inf / inf is NaN. + +module Tanh; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const TanhConfig = struct { + none : void, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // tanh(x) = (1 - e^(-2|x|)) / (1 + e^(-2|x|)), with the sign of x + fn forward(x: f32) -> f32 { + if (x < 0.0) { + return -forward(-x); + } + const t = exp(-2.0 * x); + return (1.0 - t) / (1.0 + t); + } + + // forward_batch: output[i] = tanh(input[i]) + fn forward_batch(input: []const f32, output: []f32) -> void { + var i : usize = 0; + while (i < input.len) { + output[i] = forward(input[i]); + i = i + 1; + } + } + + // tanh'(x) = 1 - tanh(x)^2 + fn derivative(x: f32) -> f32 { + const tanh_x = forward(x); + return 1.0 - (tanh_x * tanh_x); + } + + // Given y = tanh(x), the derivative is 1 - y^2 + fn derivative_from_output(tanh_x: f32) -> f32 { + return 1.0 - (tanh_x * tanh_x); + } + + fn batch_at(index: usize) -> f32 { + const input : [3]f32 = [0.0, 1.0, 2.0]; + var output : [3]f32 = [0.0] ** 3; + forward_batch(&input, &output); + return output[index]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // tanh(0) = 0, tanh(1) = 0.7615942, tanh is odd + test forward_basic_case + given input = 0.0 + when result = forward(input) + then result == 0.0 and @abs(forward(1.0) - 0.7615942) < 0.000001 and forward(-1.0) == -forward(1.0) + + // exp(2x) is inf in f32 here; the stable form still gives 1, not NaN + test forward_saturates_without_overflow + given input = 100.0 + when result = forward(input) + then result == 1.0 and forward(-100.0) == -1.0 + + test forward_batch_basic_case + given first = batch_at(0) + when second = batch_at(1) + then first == 0.0 and second > 0.0 and second < 1.0 and batch_at(2) > second + + test derivative_basic_case + given input = 0.0 + when result = derivative(input) + then result == 1.0 + + test derivative_from_output_basic_case + given input = 0.5 + when tanh_result = forward(input) + then derivative_from_output(tanh_result) > 0.0 and derivative_from_output(tanh_result) < 1.0 and derivative_from_output(tanh_result) == derivative(input) + + test derivative_matches_finite_difference + given slope = (forward(0.5 + 0.001) - forward(0.5 - 0.001)) / 0.002 + when result = derivative(0.5) + then @abs(result - slope) < 0.001 diff --git a/apps/website/public/widgets/nn-tanh/nn-tanh.t27 b/apps/website/public/widgets/nn-tanh/nn-tanh.t27 new file mode 100644 index 0000000000..e842bc0f11 --- /dev/null +++ b/apps/website/public/widgets/nn-tanh/nn-tanh.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-tanh.t27 -- tanh and the saturated band where learning stops +; Source of truth for public/widgets/nn-tanh/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-tanh/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/tanh_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 3 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 4. The curve is forward, the slope derivative, and +; every sampled x whose slope is under K_SAT is shaded red. + +; WHAT IT DOES NOT CLAIM: the threshold 0.1 is a choice made for the picture, not a constant of the +; spec. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_tanh; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-tanh"; +pub const TITLE : str = "tanh: where a neuron stops learning"; +pub const DESCRIPTION : str = "Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped."; +pub const IMAGE_ALT : str = "tanh card at x = 2.5: the green curve from -1 to 1, the dashed gold slope a bell peaking at 1, and two red bands on both sides where the slope is under 0.1. Tiles read tanh 0.9866, slope 0.0266 marked saturated, and the spec batch tanh(0, 1, 2) = 0 0.762 0.964."; +pub const HOOK : str = "tanh(2.5) is already 0.987 and its slope 0.027. Past about 1.8 either way the gradient is under 0.1: the band a deep net must stay out of."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/tanh_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 3 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 400; +pub const K_X_STEP_C : u8 = 5; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [3]i8 = [-1, 0, 1]; +pub const K_SAT_C : u8 = 10; +pub const K_PRESET_X_C : [4]i16 = [250, 0, 100, -300]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["x = 2.5", "x = 0", "x = 1", "x = -3"]; +pub const SAY_ASK : str = "Where does a neuron stop learning?"; +pub const SAY_X : str = "input x"; +pub const SAY_F : str = "tanh(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_SAT_BAND : str = "slope under 0.1"; +pub const SAY_PLOT_LABEL : str = "tanh of x and its slope from -4 to 4, saturated inputs shaded"; +pub const SAY_OUT : str = "tanh(x)"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch 0 1 2"; +pub const SAY_STATE : str = "here"; +pub const SAY_SATURATED : str = "saturated"; +pub const SAY_LEARNING : str = "still learning"; +pub const SAY_NOTE : str = "Unlike the sigmoid, tanh is centred on 0 and its slope reaches 1. It still saturates: the gradient that flows back through it is multiplied by that slope."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/tanh_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_band_threshold_is_a_tenth { + assert K_SAT_C == 10; + assert K_SAT_C < 100; +} + +test the_presets_cover_both_regions { + assert K_PRESET_X_C[0] > 150; + assert K_PRESET_X_C[1] == 0; + assert K_PRESET_X_C[3] + 150 < 0; +} diff --git a/apps/website/public/widgets/nn-tanh/tool.js b/apps/website/public/widgets/nn-tanh/tool.js new file mode 100644 index 0000000000..744473441f --- /dev/null +++ b/apps/website/public/widgets/nn-tanh/tool.js @@ -0,0 +1,40 @@ +// nn-tanh/tool.js -- lesson 3 of neural-networks: where a neuron stops learning. tanh centres the +// output on zero, and where it saturates its slope, and the gradient that flows back through it, +// falls toward zero. The curve, the slope and the shaded saturated band are forward and derivative +// of gHashTag/t27 specs/ml/activation/tanh_activation.t27, compiled to wasm (./logic.js). Words are +// SAY_ and numbers K_ constants of specs/widgets/nn-tanh.t27. +import { batchAt, derivative, forward } from './logic.js' +import { COLORS, K, W, ask, canvas, centi, controls, cursor, dragX, el, fmt, legend, plot, root, sample, say, source, svgEl, tiles } from '../nn-kit.js' + +const X0 = centi(K('K_X_LO_C', -400)), X1 = centi(K('K_X_HI_C', 400)) +const SAT = centi(K('K_SAT_C', 10)) +const ctl = controls([ + { key: 'x', label: say('SAY_X'), min: X0, max: X1, step: centi(K('K_X_STEP_C', 5)), fmt: (v) => fmt(v, 2) }, +], { names: W.SAY_PRESET_NAMES, values: { x: K('K_PRESET_X_C', []).map(centi) } }, draw) + +const svg = canvas('nn-curve', say('SAY_PLOT_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, stat, svg, legend([[say('SAY_F'), COLORS[0]], [say('SAY_DF'), COLORS[1], true], [say('SAY_SAT_BAND'), COLORS[6]]]), el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +function draw(s) { + svg.replaceChildren() + const o = { w: 640, h: 330, x0: X0, x1: X1, y0: -1.1, y1: 1.1, xticks: K('K_X_TICKS', []), yticks: K('K_Y_TICKS', []), xlabel: say('SAY_X') } + const p = plot(svg, o) + // The saturated band: every sampled x whose slope is under K_SAT, shaded. + const pts = sample((x) => derivative(x), X0, X1, 200) + const dx = (X1 - X0) / 200 + for (const [x, d] of pts) if (d < SAT) svg.append(svgEl('rect', { x: p.x(x - dx / 2), y: p.top, width: Math.max(1, p.x(x + dx / 2) - p.x(x - dx / 2)), height: p.clampY(-Infinity) - p.top, fill: COLORS[6], opacity: 0.12 })) + p.line(sample((x) => forward(x), X0, X1), COLORS[0], 3) + p.line(pts, COLORS[1], 2, { 'stroke-dasharray': '6 5' }) + cursor(svg, p, s.x, [[forward(s.x), COLORS[0]], [derivative(s.x), COLORS[1]]]) + dragX(svg, p, o, (x) => ctl.set('x', x)) + const d = derivative(s.x) + stat.replaceChildren(tiles([ + { label: say('SAY_OUT'), value: fmt(forward(s.x), 4), tone: 0 }, + { label: say('SAY_GRAD'), value: fmt(d, 4), tone: d < SAT ? 'bad' : 1 }, + { label: say('SAY_BATCH'), value: [0, 1, 2].map((i) => fmt(batchAt(i), 3)).join(' '), tone: 2 }, + { label: say('SAY_STATE'), value: d < SAT ? say('SAY_SATURATED') : say('SAY_LEARNING'), tone: d < SAT ? 'bad' : 0 }, + ])) +} + +ctl.start() diff --git a/apps/website/public/widgets/nn-xor/card.png b/apps/website/public/widgets/nn-xor/card.png new file mode 100644 index 0000000000000000000000000000000000000000..f25925aee0672f33f333a3524da45814b0e8350f GIT binary patch literal 46495 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 z + + + + + +XOR: a network learns what one neuron cannot · Trinity S³AI + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

This page sets no cookie and sends nothing anywhere.

+
Where the numbers come from
  • gHashTag/t27 specs/ml/pathway/mlp.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 20 opens this widget
+

This widget's .t27 source · All widgets

+
+ + + + diff --git a/apps/website/public/widgets/nn-xor/logic.js b/apps/website/public/widgets/nn-xor/logic.js new file mode 100644 index 0000000000..f0039ed891 --- /dev/null +++ b/apps/website/public/widgets/nn-xor/logic.js @@ -0,0 +1,32 @@ +// Generated by scripts/t27-logic.mjs from mlp.t27. Do not edit. +// +// The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). +// Change the spec in gHashTag/t27, vendor it, regenerate. A rule written +// by hand beside this file is the thing this file exists to end. +// spec-sha256: 936f35f57c99851545afe0b1797b416777549610a3f57cf49c0727311eef281a +// Imported by scripts/widget-logic.mjs for public/widgets/nn-xor/: types stripped, nothing else changed. +const WASM = "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QQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBEAMAAIAAAAAKAAAAAADGwgAAxsIAAMbCAADGwgAAxsIAAMbCAADGwgAAxsIAAMbCAADGwgAAxsI="; +const W = new WebAssembly.Instance( + new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) +).exports; +function int(v, lo, hi, at) { + if (!Number.isInteger(v) || v < lo || v > hi) + throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); + return v; +} +function mnistForward(which, index) { + return W.t27_mnist_forward(int(which, 0, 255, "mnist_forward.which"), int(index, 0, 4294967295, "mnist_forward.index")); +} +function mnistInit(which) { + return W.t27_mnist_init(int(which, 0, 255, "mnist_init.which")); +} +function xor(epochs, which) { + return W.t27_xor(int(epochs, 0, 4294967295, "xor.epochs"), int(which, 0, 4294967295, "xor.which")); +} +const __NOT_LOWERED__ = Object.freeze(["layer", "forward", "init_weights", "zero", "init", "train_step", "mnist"]); +export { + __NOT_LOWERED__, + mnistForward, + mnistInit, + xor +}; diff --git a/apps/website/public/widgets/nn-xor/logic.t27 b/apps/website/public/widgets/nn-xor/logic.t27 new file mode 100644 index 0000000000..df03c810ed --- /dev/null +++ b/apps/website/public/widgets/nn-xor/logic.t27 @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: Apache-2.0 +// t27/specs/ +// ReLU activation for hidden layers | φ² + 1/φ² = 3 | TRINITY + +// #8980: forward computed the hidden layer and wrote it into `output` (the +// second layer never ran); init called an undeclared `alloc_f32`; the tests +// called undeclared `create_test_*` helpers; and the invariants asserted `true`. +// The MLP is now two layers, h = relu(W1 x + b1) and y = W2 h + b2, over buffers +// the caller owns. train_step adds backpropagation with an SGD update, and the +// tests train the network on XOR, which no single linear layer can fit. + +module Mlp; + use base::types; + use math::constants; + + // ═══════════════════════════════════════════════════════════ + // 1. Constants + // ═══════════════════════════════════════════════════════════ + + const MNIST_INPUT_SIZE : u32 = 784; + const MNIST_OUTPUT_SIZE : u32 = 10; + const DEFAULT_HIDDEN_SIZE : u32 = 128; + + // ═══════════════════════════════════════════════════════════ + // 2. Types + // ═══════════════════════════════════════════════════════════ + + pub const MLPConfig = struct { + input_size : u32, + hidden_size : u32, + output_size : u32, + }; + + pub const MLPState = struct { + w1 : []f32, + b1 : []f32, + w2 : []f32, + b2 : []f32, + }; + + // ═══════════════════════════════════════════════════════════ + // 3. Core Functions + // ═══════════════════════════════════════════════════════════ + + // One dense layer: out[o] = sum_i w[o * n_in + i] in[i] + b[o], relu when asked + fn layer(input: []const f32, w: []const f32, b: []const f32, n_in: u32, n_out: u32, relu: bool, out: []f32) -> void { + var o : usize = 0; + while (o < n_out) { + var sum : f32 = b[o]; + var i : usize = 0; + while (i < n_in) { + sum = sum + w[o * n_in + i] * input[i]; + i = i + 1; + } + if (relu and sum < 0.0) { + sum = 0.0; + } + out[o] = sum; + o = o + 1; + } + } + + // h = relu(W1 x + b1) into `hidden`, y = W2 h + b2 into `output` + fn forward(input: []const f32, state: MLPState, hidden: []f32, output: []f32, config: MLPConfig) -> void { + layer(input, state.w1, state.b1, config.input_size, config.hidden_size, true, hidden); + layer(hidden, state.w2, state.b2, config.hidden_size, config.output_size, false, output); + } + + // He-scaled deterministic init: w in [-1, 1) sqrt(2 / fan_in) from a fixed hash of the + // index (salt tells the layers apart); every bias 0 + fn init_weights(w: []f32, fan_in: u32, salt: usize) -> void { + const scale : f32 = sqrt(2.0 / @as(f32, @floatFromInt(fan_in))); + var k : usize = 0; + while (k < w.len) { + const h : u32 = @as(u32, @intCast(((k + salt) * 2654435761) % 1000)); + w[k] = (@as(f32, @floatFromInt(h)) / 500.0 - 1.0) * scale; + k = k + 1; + } + } + + fn zero(v: []f32) -> void { + var k : usize = 0; + while (k < v.len) { + v[k] = 0.0; + k = k + 1; + } + } + + fn init(state: MLPState, config: MLPConfig) -> void { + init_weights(state.w1, config.input_size, 1); + zero(state.b1); + init_weights(state.w2, config.hidden_size, 7); + zero(state.b2); + } + + // One SGD step on the loss 0.5 * sum_o (y_o - t_o)^2; returns the loss before the step. + // d2_o = y_o - t_o (output error) + // d1_i = [z_i > 0] sum_o W2[o][i] d2_o (backpropagated through relu) + // W2 -= lr d2 h^T, b2 -= lr d2; W1 -= lr d1 x^T, b1 -= lr d1 + fn train_step(input: []const f32, target: []const f32, state: MLPState, hidden: []f32, delta: []f32, output: []f32, lr: f32, config: MLPConfig) -> f32 { + forward(input, state, hidden, output, config); + var loss : f32 = 0.0; + var o : usize = 0; + while (o < config.output_size) { + const e = output[o] - target[o]; + loss = loss + 0.5 * e * e; + o = o + 1; + } + var i : usize = 0; + while (i < config.hidden_size) { + var back : f32 = 0.0; + if (hidden[i] > 0.0) { + o = 0; + while (o < config.output_size) { + back = back + state.w2[o * config.hidden_size + i] * (output[o] - target[o]); + o = o + 1; + } + } + delta[i] = back; + i = i + 1; + } + o = 0; + while (o < config.output_size) { + const d2 = output[o] - target[o]; + i = 0; + while (i < config.hidden_size) { + state.w2[o * config.hidden_size + i] = state.w2[o * config.hidden_size + i] - lr * d2 * hidden[i]; + i = i + 1; + } + state.b2[o] = state.b2[o] - lr * d2; + o = o + 1; + } + i = 0; + while (i < config.hidden_size) { + var j : usize = 0; + while (j < config.input_size) { + state.w1[i * config.input_size + j] = state.w1[i * config.input_size + j] - lr * delta[i] * input[j]; + j = j + 1; + } + state.b1[i] = state.b1[i] - lr * delta[i]; + i = i + 1; + } + return loss; + } + + fn mnist() -> MLPConfig { + return MLPConfig{ .input_size = MNIST_INPUT_SIZE, .hidden_size = DEFAULT_HIDDEN_SIZE, .output_size = MNIST_OUTPUT_SIZE }; + } + + // which: 0 = output[index], 1 = min over every output, 2 = number of outputs written, + // on the MNIST shape with input pixel k = (k % 7) / 7 + fn mnist_forward(which: u8, index: usize) -> f32 { + var w1 : [784 * 128]f32 = undefined; + var b1 : [128]f32 = undefined; + var w2 : [128 * 10]f32 = undefined; + var b2 : [10]f32 = undefined; + const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }; + init(state, mnist()); + var input : [784]f32 = undefined; + var k : usize = 0; + while (k < 784) { + input[k] = @as(f32, @floatFromInt(k % 7)) / 7.0; + k = k + 1; + } + var hidden : [128]f32 = undefined; + var output : [11]f32 = [-99.0] ** 11; + forward(&input, state, &hidden, &output, mnist()); + if (which == 0) { + return output[index]; + } + var min_h : f32 = hidden[0]; + var written : f32 = 0.0; + k = 0; + while (k < 128) { + min_h = @min(min_h, hidden[k]); + k = k + 1; + } + k = 0; + while (k < 11) { + if (output[k] != -99.0) { + written = written + 1.0; + } + k = k + 1; + } + if (which == 1) { + return min_h; + } + return written; + } + + // which: 0 = w1.len written by init, 1 = b1[0], 2 = b2[0], 3 = largest |w1| + fn mnist_init(which: u8) -> f32 { + var w1 : [784 * 128]f32 = [9.0] ** (784 * 128); + var b1 : [128]f32 = [9.0] ** 128; + var w2 : [128 * 10]f32 = [9.0] ** (128 * 10); + var b2 : [10]f32 = [9.0] ** 10; + init(MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, mnist()); + var written : f32 = 0.0; + var largest : f32 = 0.0; + var k : usize = 0; + while (k < w1.len) { + if (w1[k] != 9.0) { + written = written + 1.0; + } + largest = @max(largest, @abs(w1[k])); + k = k + 1; + } + if (which == 0) { + return written; + } + if (which == 1) { + return b1[0]; + } + if (which == 2) { + return b2[0]; + } + return largest; + } + + // Train a 2-8-1 network on XOR for `epochs` passes over the four cases. + // which: 0 = total loss of the first epoch, 1 = total loss of the last epoch, + // 2 + c = the trained network's output for case c + fn xor(epochs: u32, which: usize) -> f32 { + const cfg = MLPConfig{ .input_size = 2, .hidden_size = 8, .output_size = 1 }; + var w1 : [16]f32 = undefined; + var b1 : [8]f32 = undefined; + var w2 : [8]f32 = undefined; + var b2 : [1]f32 = undefined; + const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }; + init(state, cfg); + const xs : [8]f32 = [0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]; + const ts : [4]f32 = [0.0, 1.0, 1.0, 0.0]; + var hidden : [8]f32 = undefined; + var delta : [8]f32 = undefined; + var output : [1]f32 = undefined; + var first : f32 = 0.0; + var last : f32 = 0.0; + var e : u32 = 0; + while (e < epochs) { + var total : f32 = 0.0; + var c : usize = 0; + while (c < 4) { + total = total + train_step(xs[c * 2 .. c * 2 + 2], ts[c .. c + 1], state, &hidden, &delta, &output, 0.05, cfg); + c = c + 1; + } + if (e == 0) { + first = total; + } + last = total; + e = e + 1; + } + if (which == 0) { + return first; + } + if (which == 1) { + return last; + } + forward(xs[(which - 2) * 2 .. (which - 2) * 2 + 2], state, &hidden, &output, cfg); + return output[0]; + } + + // ═══════════════════════════════════════════════════════════ + // TDD: Tests (from .tri behaviors) + // ═══════════════════════════════════════════════════════════ + + // 784 -> 128 -> 10: exactly the 10 outputs are written, the 11th slot is untouched + test forward_output_size + given written = mnist_forward(2, 0) + when spare = mnist_forward(0, 10) + then written == 10.0 and spare == -99.0 + + // The hidden layer is relu, so no hidden unit is negative + test forward_relu_activation + given min_hidden = mnist_forward(1, 0) + then min_hidden >= 0.0 + + // init writes every one of the 784 * 128 first-layer weights, each within sqrt(2 / 784) = 0.05051 + test init_allocation_sizes + given written = mnist_init(0) + when largest = mnist_init(3) + then written == 100352.0 and largest <= 0.0506 and largest > 0.0 + + test init_bias_initialization + given b1 = mnist_init(1) + when b2 = mnist_init(2) + then b1 == 0.0 and b2 == 0.0 + + // Backpropagation learns XOR: the loss falls by more than 100x, and each output is within 0.1 + test train_step_learns_xor + given first = xor(2000, 0) + when last = xor(2000, 1) + then last < first / 100.0 and @abs(xor(2000, 2)) < 0.1 and @abs(xor(2000, 3) - 1.0) < 0.1 and @abs(xor(2000, 4) - 1.0) < 0.1 and @abs(xor(2000, 5)) < 0.1 + + // ═══════════════════════════════════════════════════════════ + // TDD: Invariants (from .tri constraints) + // ═══════════════════════════════════════════════════════════ + + // input_size == MNIST_INPUT_SIZE (784) + invariant mlp_constraint_0 + assert mnist().input_size == 784 + + // output_size == MNIST_OUTPUT_SIZE (10) + invariant mlp_constraint_1 + assert mnist().output_size == 10 + + // hidden_size > 0 + invariant mlp_constraint_2 + assert mnist().hidden_size > 0 + + // w1.size() == input_size * hidden_size + invariant mlp_constraint_3 + assert mnist().input_size * mnist().hidden_size == 100352 + + // w2.size() == hidden_size * output_size + invariant mlp_constraint_4 + assert mnist().hidden_size * mnist().output_size == 1280 + + // b1.size() == hidden_size + invariant mlp_constraint_5 + assert DEFAULT_HIDDEN_SIZE == 128 + + // b2.size() == output_size + invariant mlp_constraint_6 + assert MNIST_OUTPUT_SIZE == 10 diff --git a/apps/website/public/widgets/nn-xor/nn-xor.t27 b/apps/website/public/widgets/nn-xor/nn-xor.t27 new file mode 100644 index 0000000000..262c463c48 --- /dev/null +++ b/apps/website/public/widgets/nn-xor/nn-xor.t27 @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-xor.t27 -- a 2-8-1 network learns XOR by backpropagation +; Source of truth for public/widgets/nn-xor/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-xor/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/pathway/mlp.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 20 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the epochs from 0 to 2000. Every output is xor(epochs, 2 + c), the +; loss curve xor(e, 1) every 25 epochs and the first-epoch loss xor(e, 0): the spec trains its own +; 2-8-1 network from fixed initial weights at lr 0.05, from scratch on every call. + +; WHAT IT DOES NOT CLAIM: the grid shows the four inputs the spec exposes, not a decision region +; over the plane: the spec has no fn for a point between the corners. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_xor; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-xor"; +pub const TITLE : str = "XOR: a network learns what one neuron cannot"; +pub const DESCRIPTION : str = "A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders."; +pub const IMAGE_ALT : str = "XOR card after 2000 epochs: a 2 x 2 grid of the four cases, dark blue 0.000 on the diagonal and white 1.000 off it. Beside it a red loss curve on a log axis falls from 0.89 at epoch 1 to about 1e-13 at 2000. Tiles read first-epoch loss 0.8896, last 1.78e-13, outputs 0.00 1.00 1.00 0.00 against the targets 0 1 1 0."; +pub const HOOK : str = "One neuron cannot draw XOR. Eight hidden units can: after 2000 epochs the outputs are 0, 1, 1, 0 to within 4e-7 and the loss is 1.8e-13."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/pathway/mlp.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 20 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_EPOCHS_HI : u16 = 2000; +pub const K_CURVE_STEP : u8 = 25; +pub const K_LOG_LO : i8 = -14; +pub const K_LOG_HI : u8 = 1; +pub const K_LOG_TICKS : [5]i8 = [-12, -9, -6, -3, 0]; +pub const K_EPOCH_TICKS : [5]u16 = [0, 500, 1000, 1500, 2000]; +pub const K_CASES : [4]u8 = [0, 1, 1, 0]; +pub const K_PRESET_EPOCHS : [4]u16 = [2000, 0, 100, 500]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Trained, 2000 epochs", "Untrained", "100 epochs", "500 epochs"]; +pub const SAY_ASK : str = "Can a network learn something one neuron cannot?"; +pub const SAY_EPOCHS : str = "epochs"; +pub const SAY_A : str = "a ="; +pub const SAY_B : str = "b ="; +pub const SAY_CURVE_LABEL : str = "The training loss, log scale"; +pub const SAY_GRID_LABEL : str = "The network's answer for each input (a, b)"; +pub const SAY_LOG_NOTE : str = "log scale"; +pub const SAY_FIRST_LOSS : str = "loss, epoch 1"; +pub const SAY_LAST_LOSS : str = "loss, last epoch"; +pub const SAY_UNTRAINED : str = "not trained"; +pub const SAY_OUTPUTS : str = "outputs 00 01 10 11"; +pub const SAY_TARGETS : str = "targets"; +pub const SAY_NOTE : str = "XOR is 1 when exactly one input is 1. No straight line separates its 1s from its 0s, so one neuron fails; a hidden layer of ReLUs bends the space until one does."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/pathway/mlp.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_curve_steps_divide_the_run { + assert K_EPOCHS_HI % K_CURVE_STEP == 0; + assert K_EPOCHS_HI / K_CURVE_STEP == 80; +} + +test the_targets_are_xor { + assert K_CASES[0] == 0; + assert K_CASES[1] == 1; + assert K_CASES[2] == 1; + assert K_CASES[3] == 0; + assert K_PRESET_EPOCHS[0] == K_EPOCHS_HI; +} diff --git a/apps/website/public/widgets/nn-xor/tool.js b/apps/website/public/widgets/nn-xor/tool.js new file mode 100644 index 0000000000..af4781e3c8 --- /dev/null +++ b/apps/website/public/widgets/nn-xor/tool.js @@ -0,0 +1,46 @@ +// nn-xor/tool.js -- lesson 20 of neural-networks: can a network learn what one neuron cannot? XOR +// is not linearly separable, yet a 2-8-1 network trained by backpropagation gets all four cases +// right. Every output and every point of the loss curve is xor(epochs, which) of gHashTag/t27 +// specs/ml/pathway/mlp.t27, compiled to wasm (./logic.js): the spec trains from its own fixed +// initial weights, lr 0.05, each call from scratch. The four squares are the four inputs the spec +// exposes, not the whole plane. Words are SAY_ and numbers K_ constants of specs/widgets/nn-xor.t27. +import { xor } from './logic.js' +import { COLORS, K, W, ask, canvas, controls, cursor, dragX, el, fmt, heat, heatTone, plot, root, say, source, svgEl, tiles } from '../nn-kit.js' + +const EMAX = K('K_EPOCHS_HI', 2000), STEP = K('K_CURVE_STEP', 25) +const LOG0 = K('K_LOG_LO', -14), LOG1 = K('K_LOG_HI', 1) +const ctl = controls([ + { key: 'e', label: say('SAY_EPOCHS'), min: 0, max: EMAX, step: STEP }, +], { names: W.SAY_PRESET_NAMES, values: { e: K('K_PRESET_EPOCHS', []) } }, draw) + +const svg = canvas('nn-curve', say('SAY_CURVE_LABEL')) +const grid = canvas('nn-heat', say('SAY_GRID_LABEL')) +const stat = el('div') +root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('div', { class: 'nn-two' }, el('div', {}, el('p', { class: 'dk-label' }, say('SAY_GRID_LABEL')), grid), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_CURVE_LABEL')), svg)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) + +// The loss after every STEP epochs, trained once and kept: each point is a full run of the spec. +let curve = null +const lossCurve = () => (curve ??= [...Array(EMAX / STEP)].map((_, k) => [(k + 1) * STEP, xor((k + 1) * STEP, 1)])) +const lg = (v) => Math.log10(Math.max(v, 10 ** LOG0)) + +function draw(s) { + const cases = K('K_CASES', []) + const out = [0, 1, 2, 3].map((c) => (s.e > 0 ? xor(s.e, 2 + c) : xor(0, 2 + c))) + heat(grid, { rows: 2, cols: 2, value: (r, c) => out[r * 2 + c], color: (v) => heatTone(v), rowLabels: [`${say('SAY_A')} 0`, `${say('SAY_A')} 1`], colLabels: [`${say('SAY_B')} 0`, `${say('SAY_B')} 1`], labelWidth: 60, w: 400, cell: 150, fmt: (v) => fmt(v, 3) }) + svg.replaceChildren() + const o = { w: 640, h: 330, x0: 0, x1: EMAX, y0: LOG0, y1: LOG1, xticks: K('K_EPOCH_TICKS', []), yticks: K('K_LOG_TICKS', []), yfmt: (t) => `1e${t}`, xlabel: say('SAY_EPOCHS') } + const p = plot(svg, o) + p.line(lossCurve().map(([e, v]) => [e, lg(v)]), COLORS[6], 3) + const now = s.e > 0 ? xor(s.e, 1) : xor(1, 0) + cursor(svg, p, s.e, [[lg(now), COLORS[1]]]) + dragX(svg, p, o, (e) => ctl.set('e', Math.round(e / STEP) * STEP)) + svg.append(svgEl('text', { x: p.x(EMAX) - 6, y: p.top + 16, class: 'dk-txt-dim', 'text-anchor': 'end' }, say('SAY_LOG_NOTE'))) + stat.replaceChildren(tiles([ + { label: say('SAY_FIRST_LOSS'), value: fmt(xor(Math.max(1, s.e), 0), 4), tone: 6 }, + { label: say('SAY_LAST_LOSS'), value: s.e > 0 ? xor(s.e, 1).toExponential(2) : say('SAY_UNTRAINED'), tone: 1 }, + { label: say('SAY_OUTPUTS'), value: out.map((v) => fmt(v, 2)).join(' '), tone: 0 }, + { label: say('SAY_TARGETS'), value: cases.join(' '), tone: 2 }, + ])) +} + +ctl.start() diff --git a/apps/website/specs/widgets/gallery.t27 b/apps/website/specs/widgets/gallery.t27 index 6285d9a4d1..17117ac2a9 100644 --- a/apps/website/specs/widgets/gallery.t27 +++ b/apps/website/specs/widgets/gallery.t27 @@ -78,15 +78,15 @@ pub const TOOL_NOSCRIPT : str = "This widget runs in your browser and needs Java ; Parallel arrays, WIDGET_COUNT long. WIDGET_TITLES is empty wherever the page carries an ; og:title, which is every kind but tab: the page is the one place the words live. A tool's ; WIDGET_HOOKS entry is empty too: its hook is the page's t27:hook, written from its own spec. -pub const WIDGET_COUNT : u8 = 252; -pub const WIDGET_IDS : [252]str = ["x7-board", "tri-x7-fasm", "tri-x7-mutate", "perf2-loop", "tri-fpga-rgmii", "tri-fpga-jtag", "tri-fpga-pins", "devkit-flow", "play-verilog", "bit-diff", "build-receipt", "cost-curves", "gf16-calc", "idcode", "lut-explain", "pin-map", "placement-map", "resource-bars", "slack-waterfall", "test-waves", "synth-smells", "bit-autopsy", "fasm-skyline", "vcd-wrapped", "fits-on", "stat-card", "lut-depth", "fsm-sketch", "lut-treemap", "t27-cell", "t27-vs-nvfp4", "uart-bucket", "tri-fpga-specs", "tri-fpga-tools", "tri-fpga-wire", "tri-fpga-batch", "tri-fpga-status", "tri-fpga-tmpcheck", "tri-fpga-keycheck", "tri-fpga-selftest", "tri-x7-refs", "tri-x7-audit", "t27c-clock-domain", "t27c-clocks", "t27c-wukong-v1", "t27c-cts", "t27c-mmcm", "t27c-mmcm-mutate", "t27c-timing", "t27c-reset-sync", "t27c-reset-sync-gen", "t27c-mtbf", "t27c-clock-domain-gen", "t27c-fifo", "t27c-fifo-mutate", "t27c-fifo-flags", "t27c-emitter-xdc", "t27c-fpga-rxcap", "t27-tri-competitors", "t27-tri-discard", "tri-fpga-txhold", "tri-fpga-rxcap", "tri-fpga-rxer", "tri-fpga-steps", "tri-fpga-ioclients", "tri-fpga-claim", "tri-fpga-release", "tri-fpga-next", "t27c-memory", "t27c-spi-tb", "t27c-check-uart", "t27c-check-spi", "t27c-check-apb", "t27c-check-axi4", "t27c-check-bridge", "t27c-check-memory", "t27c-verilog-uart", "t27c-verilog-spi", "t27c-verilog-apb", "t27c-verilog-axi4", "t27c-verilog-bridge", "t27c-verilog-top", "t27c-verilog-uart-tb", "t27c-verilog-apb-tb", "t27c-verilog-axi-tb", "t27c-verilog-mem-tb", "t27c-verilog-integration-tb", "t27c-verilog-top-tb", "t27c-verilog-spi-tb", "t27c-hir-uart", "t27c-hir-apb", "t27c-hir-axi4", "t27c-eth-crc", "t27c-rgmii", "jtag-verdict", "line-bounce", "eye-isi", "ecc-secded", "carry-chain", "prefix-adder", "csa-tree", "shift-add", "booth-radix4", "dsp-fit", "q-format", "round-sat", "sqnr", "cordic", "cordic-vector", "sine-table", "alias-fold", "nco", "dft-bin", "fir-response", "fir-design", "fir-cost", "decimator", "cic-growth", "polyphase", "fft-butterfly", "bit-reverse", "fft-scaling", "barker-corr", "fir-fit", "fir-on-board", "play-hello-world", "play-rust", "play-js", "t27c-hello-world", "t27-tri-misread", "test-touch", "t27c-stages", "t27c-e8m0", "play-e8m0", "t27c-ocp-mx", "play-gfternary", "t27c-gfternary", "play-golden-sieve", "t27c-golden-sieve", "play-tnf17", "t27c-tnf17", "t27c-activation-quantizer", "t27c-bitnet-majority", "t27c-bitnet-neuron-nchunk", "t27c-comb-ternary-dot", "t27c-stream-ternary-mac", "t27c-bitnet-mlp", "t27c-gft-smul", "t27c-gft-sadd", "t27c-gft-signed-mac", "t27c-gft-relu", "t27c-gft-exp2", "t27c-gft-argmax4", "t27c-gft-nll", "t27c-gft-sgd-step", "t27c-gft-xornet", "basics-what-a-spec-is", "basics-the-module-line", "basics-comments-and-prose", "basics-constants", "basics-whole-numbers", "basics-true-false-and-text", "basics-arrays", "basics-trits", "basics-expressions", "basics-a-test-block", "basics-many-tests", "basics-functions", "basics-local-names", "basics-if-and-else", "basics-loops", "basics-pub-or-private", "basics-structs", "basics-enums", "basics-use-other-modules", "basics-invariants", "basics-gen-ts", "basics-seven-backends", "basics-stages-of-t27c", "basics-tri-commands", "basics-reading-errors", "basics-a-small-program", "basics-where-next", "golden-split", "golden-phi-ratio", "golden-lucas", "golden-split-optimality", "golden-radix-economy", "golden-phi-in-gf16", "golden-gf4", "golden-gf6", "golden-gf8", "golden-gf10", "golden-gf12", "golden-gf14", "golden-gf16", "golden-dot-two", "golden-gf24", "golden-gf32", "golden-gf48", "golden-gf64", "golden-gf96", "golden-gf128", "golden-gf256", "golden-gf512", "golden-gf1024", "golden-gft8", "golden-gft16", "golden-gft32", "golden-decode", "t27-tri-vectors", "t27-tri-census", "t27-tri-seals", "t27-tri-prose", "t27-tri-lean", "tri-selftest", "play-terminal-gates", "tc-why-three", "tc-balanced-count", "tc-flip-and-cut", "tc-kleene-gates", "tc-consensus-any", "tc-sum-and-carry", "tc-half-adder", "tc-full-adder", "tc-ripple-carry", "tc-times-a-trit", "tc-long-multiply", "tc-ternary-mac", "tc-two-bits", "tc-five-in-a-byte", "tc-trit-word", "tc-instruction-word", "tc-opcode-map", "tc-immediate", "tc-ternary-alu", "tc-three-way-jump", "tc-run-a-program", "tc-compare", "tc-thirds", "tc-sort-three", "tc-one-neuron", "tc-detector", "tc-tiny-layer", "wars", "tri-game-tick", "tri-game-vault", "perf2-knockouts", "race-the-bee", "gatle", "tri-blog-list", "tri-game-selftest"]; -pub const WIDGET_KINDS : [252]str = ["cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "player", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "player", "player", "player", "cast", "cast", "tool", "tool", "cast", "player", "cast", "player", "cast", "player", "cast", "player", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tab", "cast", "cast", "cast", "tool", "tool", "cast", "cast"]; -pub const WIDGET_CATEGORIES : [252]str = ["fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "game", "game", "game", "game", "game", "game", "game", "game"]; -pub const WIDGET_PAGES : [252]str = ["term/x7-board/", "term/tri-x7-fasm/", "term/tri-x7-mutate/", "term/perf2-loop/", "term/tri-fpga-rgmii/", "term/tri-fpga-jtag/", "term/tri-fpga-pins/", "term/devkit-flow/", "play/hello-world/verilog/", "widgets/bit-diff/", "widgets/build-receipt/", "widgets/cost-curves/", "widgets/gf16-calc/", "widgets/idcode/", "widgets/lut-explain/", "widgets/pin-map/", "widgets/placement-map/", "widgets/resource-bars/", "widgets/slack-waterfall/", "widgets/test-waves/", "widgets/synth-smells/", "widgets/bit-autopsy/", "widgets/fasm-skyline/", "widgets/vcd-wrapped/", "widgets/fits-on/", "widgets/stat-card/", "widgets/lut-depth/", "widgets/fsm-sketch/", "widgets/lut-treemap/", "widgets/t27-cell/", "widgets/t27-vs-nvfp4/", "widgets/uart-bucket/", "term/tri-fpga-specs/", "term/tri-fpga-tools/", "term/tri-fpga-wire/", "term/tri-fpga-batch/", "term/tri-fpga-status/", "term/tri-fpga-tmpcheck/", "term/tri-fpga-keycheck/", "term/tri-fpga-selftest/", "term/tri-x7-refs/", "term/tri-x7-audit/", "term/t27c-clock-domain/", "term/t27c-clocks/", "term/t27c-wukong-v1/", "term/t27c-cts/", "term/t27c-mmcm/", "term/t27c-mmcm-mutate/", "term/t27c-timing/", "term/t27c-reset-sync/", "term/t27c-reset-sync-gen/", "term/t27c-mtbf/", "term/t27c-clock-domain-gen/", "term/t27c-fifo/", "term/t27c-fifo-mutate/", "term/t27c-fifo-flags/", "term/t27c-emitter-xdc/", "term/t27c-fpga-rxcap/", "term/t27-tri-competitors/", "term/t27-tri-discard/", "term/tri-fpga-txhold/", "term/tri-fpga-rxcap/", "term/tri-fpga-rxer/", "term/tri-fpga-steps/", "term/tri-fpga-ioclients/", "term/tri-fpga-claim/", "term/tri-fpga-release/", "term/tri-fpga-next/", "term/t27c-memory/", "term/t27c-spi-tb/", "term/t27c-check-uart/", "term/t27c-check-spi/", "term/t27c-check-apb/", "term/t27c-check-axi4/", "term/t27c-check-bridge/", "term/t27c-check-memory/", "term/t27c-verilog-uart/", "term/t27c-verilog-spi/", "term/t27c-verilog-apb/", "term/t27c-verilog-axi4/", "term/t27c-verilog-bridge/", "term/t27c-verilog-top/", "term/t27c-verilog-uart-tb/", "term/t27c-verilog-apb-tb/", "term/t27c-verilog-axi-tb/", "term/t27c-verilog-mem-tb/", "term/t27c-verilog-integration-tb/", "term/t27c-verilog-top-tb/", "term/t27c-verilog-spi-tb/", "term/t27c-hir-uart/", "term/t27c-hir-apb/", "term/t27c-hir-axi4/", "term/t27c-eth-crc/", "term/t27c-rgmii/", "widgets/jtag-verdict/", "widgets/line-bounce/", "widgets/eye-isi/", "widgets/ecc-secded/", "widgets/carry-chain/", "widgets/prefix-adder/", "widgets/csa-tree/", "widgets/shift-add/", "widgets/booth-radix4/", "widgets/dsp-fit/", "widgets/q-format/", "widgets/round-sat/", "widgets/sqnr/", "widgets/cordic/", "widgets/cordic-vector/", "widgets/sine-table/", "widgets/alias-fold/", "widgets/nco/", "widgets/dft-bin/", "widgets/fir-response/", "widgets/fir-design/", "widgets/fir-cost/", "widgets/decimator/", "widgets/cic-growth/", "widgets/polyphase/", "widgets/fft-butterfly/", "widgets/bit-reverse/", "widgets/fft-scaling/", "widgets/barker-corr/", "widgets/fir-fit/", "widgets/fir-on-board/", "play/hello-world/", "play/hello-world/rust/", "play/hello-world/js/", "term/t27c-hello-world/", "term/t27-tri-misread/", "widgets/test-touch/", "widgets/t27c-stages/", "term/t27c-e8m0/", "play/e8m0/", "term/t27c-ocp-mx/", "play/gfternary/", "term/t27c-gfternary/", "play/golden-sieve/", "term/t27c-golden-sieve/", "play/tnf17/", "term/t27c-tnf17/", "term/t27c-activation-quantizer/", "term/t27c-bitnet-majority/", "term/t27c-bitnet-neuron-nchunk/", "term/t27c-comb-ternary-dot/", "term/t27c-stream-ternary-mac/", "term/t27c-bitnet-mlp/", "term/t27c-gft-smul/", "term/t27c-gft-sadd/", "term/t27c-gft-signed-mac/", "term/t27c-gft-relu/", "term/t27c-gft-exp2/", "term/t27c-gft-argmax4/", "term/t27c-gft-nll/", "term/t27c-gft-sgd-step/", "term/t27c-gft-xornet/", "widgets/basics-what-a-spec-is/", "widgets/basics-the-module-line/", "widgets/basics-comments-and-prose/", "widgets/basics-constants/", "widgets/basics-whole-numbers/", "widgets/basics-true-false-and-text/", "widgets/basics-arrays/", "widgets/basics-trits/", "widgets/basics-expressions/", "widgets/basics-a-test-block/", "widgets/basics-many-tests/", "widgets/basics-functions/", "widgets/basics-local-names/", "widgets/basics-if-and-else/", "widgets/basics-loops/", "widgets/basics-pub-or-private/", "widgets/basics-structs/", "widgets/basics-enums/", "widgets/basics-use-other-modules/", "widgets/basics-invariants/", "widgets/basics-gen-ts/", "widgets/basics-seven-backends/", "widgets/basics-stages-of-t27c/", "widgets/basics-tri-commands/", "widgets/basics-reading-errors/", "widgets/basics-a-small-program/", "widgets/basics-where-next/", "widgets/golden-split/", "widgets/golden-phi-ratio/", "widgets/golden-lucas/", "widgets/golden-split-optimality/", "widgets/golden-radix-economy/", "widgets/golden-phi-in-gf16/", "widgets/golden-gf4/", "widgets/golden-gf6/", "widgets/golden-gf8/", "widgets/golden-gf10/", "widgets/golden-gf12/", "widgets/golden-gf14/", "widgets/golden-gf16/", "widgets/golden-dot-two/", "widgets/golden-gf24/", "widgets/golden-gf32/", "widgets/golden-gf48/", "widgets/golden-gf64/", "widgets/golden-gf96/", "widgets/golden-gf128/", "widgets/golden-gf256/", "widgets/golden-gf512/", "widgets/golden-gf1024/", "widgets/golden-gft8/", "widgets/golden-gft16/", "widgets/golden-gft32/", "widgets/golden-decode/", "term/t27-tri-vectors/", "term/t27-tri-census/", "term/t27-tri-seals/", "term/t27-tri-prose/", "term/t27-tri-lean/", "term/tri-selftest/", "term/play-terminal-gates/", "widgets/tc-why-three/", "widgets/tc-balanced-count/", "widgets/tc-flip-and-cut/", "widgets/tc-kleene-gates/", "widgets/tc-consensus-any/", "widgets/tc-sum-and-carry/", "widgets/tc-half-adder/", "widgets/tc-full-adder/", "widgets/tc-ripple-carry/", "widgets/tc-times-a-trit/", "widgets/tc-long-multiply/", "widgets/tc-ternary-mac/", "widgets/tc-two-bits/", "widgets/tc-five-in-a-byte/", "widgets/tc-trit-word/", "widgets/tc-instruction-word/", "widgets/tc-opcode-map/", "widgets/tc-immediate/", "widgets/tc-ternary-alu/", "widgets/tc-three-way-jump/", "widgets/tc-run-a-program/", "widgets/tc-compare/", "widgets/tc-thirds/", "widgets/tc-sort-three/", "widgets/tc-one-neuron/", "widgets/tc-detector/", "widgets/tc-tiny-layer/", "wars", "term/tri-game-tick/", "term/tri-game-vault/", "term/perf2-knockouts/", "widgets/race-the-bee/", "widgets/gatle/", "term/tri-blog-list/", "term/tri-game-selftest/"]; -pub const WIDGET_TITLES : [252]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "WARS: agent configurations compared on real GitHub issues", "", "", "", "", "", "", ""]; -pub const WIDGET_LINES : [252]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "One issue, one pinned commit, the same tools and gates; only the decision layer changes, and a missing run stays unknown.", "", "", "", "", "", "", ""]; +pub const WIDGET_COUNT : u16 = 279; +pub const WIDGET_IDS : [279]str = ["x7-board", "tri-x7-fasm", "tri-x7-mutate", "perf2-loop", "tri-fpga-rgmii", "tri-fpga-jtag", "tri-fpga-pins", "devkit-flow", "play-verilog", "bit-diff", "build-receipt", "cost-curves", "gf16-calc", "idcode", "lut-explain", "pin-map", "placement-map", "resource-bars", "slack-waterfall", "test-waves", "synth-smells", "bit-autopsy", "fasm-skyline", "vcd-wrapped", "fits-on", "stat-card", "lut-depth", "fsm-sketch", "lut-treemap", "t27-cell", "t27-vs-nvfp4", "uart-bucket", "tri-fpga-specs", "tri-fpga-tools", "tri-fpga-wire", "tri-fpga-batch", "tri-fpga-status", "tri-fpga-tmpcheck", "tri-fpga-keycheck", "tri-fpga-selftest", "tri-x7-refs", "tri-x7-audit", "t27c-clock-domain", "t27c-clocks", "t27c-wukong-v1", "t27c-cts", "t27c-mmcm", "t27c-mmcm-mutate", "t27c-timing", "t27c-reset-sync", "t27c-reset-sync-gen", "t27c-mtbf", "t27c-clock-domain-gen", "t27c-fifo", "t27c-fifo-mutate", "t27c-fifo-flags", "t27c-emitter-xdc", "t27c-fpga-rxcap", "t27-tri-competitors", "t27-tri-discard", "tri-fpga-txhold", "tri-fpga-rxcap", "tri-fpga-rxer", "tri-fpga-steps", "tri-fpga-ioclients", "tri-fpga-claim", "tri-fpga-release", "tri-fpga-next", "t27c-memory", "t27c-spi-tb", "t27c-check-uart", "t27c-check-spi", "t27c-check-apb", "t27c-check-axi4", "t27c-check-bridge", "t27c-check-memory", "t27c-verilog-uart", "t27c-verilog-spi", "t27c-verilog-apb", "t27c-verilog-axi4", "t27c-verilog-bridge", "t27c-verilog-top", "t27c-verilog-uart-tb", "t27c-verilog-apb-tb", "t27c-verilog-axi-tb", "t27c-verilog-mem-tb", "t27c-verilog-integration-tb", "t27c-verilog-top-tb", "t27c-verilog-spi-tb", "t27c-hir-uart", "t27c-hir-apb", "t27c-hir-axi4", "t27c-eth-crc", "t27c-rgmii", "jtag-verdict", "line-bounce", "eye-isi", "ecc-secded", "carry-chain", "prefix-adder", "csa-tree", "shift-add", "booth-radix4", "dsp-fit", "q-format", "round-sat", "sqnr", "cordic", "cordic-vector", "sine-table", "alias-fold", "nco", "dft-bin", "fir-response", "fir-design", "fir-cost", "decimator", "cic-growth", "polyphase", "fft-butterfly", "bit-reverse", "fft-scaling", "barker-corr", "fir-fit", "fir-on-board", "play-hello-world", "play-rust", "play-js", "t27c-hello-world", "t27-tri-misread", "test-touch", "t27c-stages", "t27c-e8m0", "play-e8m0", "t27c-ocp-mx", "play-gfternary", "t27c-gfternary", "play-golden-sieve", "t27c-golden-sieve", "play-tnf17", "t27c-tnf17", "t27c-activation-quantizer", "t27c-bitnet-majority", "t27c-bitnet-neuron-nchunk", "t27c-comb-ternary-dot", "t27c-stream-ternary-mac", "t27c-bitnet-mlp", "t27c-gft-smul", "t27c-gft-sadd", "t27c-gft-signed-mac", "t27c-gft-relu", "t27c-gft-exp2", "t27c-gft-argmax4", "t27c-gft-nll", "t27c-gft-sgd-step", "t27c-gft-xornet", "basics-what-a-spec-is", "basics-the-module-line", "basics-comments-and-prose", "basics-constants", "basics-whole-numbers", "basics-true-false-and-text", "basics-arrays", "basics-trits", "basics-expressions", "basics-a-test-block", "basics-many-tests", "basics-functions", "basics-local-names", "basics-if-and-else", "basics-loops", "basics-pub-or-private", "basics-structs", "basics-enums", "basics-use-other-modules", "basics-invariants", "basics-gen-ts", "basics-seven-backends", "basics-stages-of-t27c", "basics-tri-commands", "basics-reading-errors", "basics-a-small-program", "basics-where-next", "golden-split", "golden-phi-ratio", "golden-lucas", "golden-split-optimality", "golden-radix-economy", "golden-phi-in-gf16", "golden-gf4", "golden-gf6", "golden-gf8", "golden-gf10", "golden-gf12", "golden-gf14", "golden-gf16", "golden-dot-two", "golden-gf24", "golden-gf32", "golden-gf48", "golden-gf64", "golden-gf96", "golden-gf128", "golden-gf256", "golden-gf512", "golden-gf1024", "golden-gft8", "golden-gft16", "golden-gft32", "golden-decode", "t27-tri-vectors", "t27-tri-census", "t27-tri-seals", "t27-tri-prose", "t27-tri-lean", "tri-selftest", "play-terminal-gates", "tc-why-three", "tc-balanced-count", "tc-flip-and-cut", "tc-kleene-gates", "tc-consensus-any", "tc-sum-and-carry", "tc-half-adder", "tc-full-adder", "tc-ripple-carry", "tc-times-a-trit", "tc-long-multiply", "tc-ternary-mac", "tc-two-bits", "tc-five-in-a-byte", "tc-trit-word", "tc-instruction-word", "tc-opcode-map", "tc-immediate", "tc-ternary-alu", "tc-three-way-jump", "tc-run-a-program", "tc-compare", "tc-thirds", "tc-sort-three", "tc-one-neuron", "tc-detector", "tc-tiny-layer", "nn-relu", "nn-sigmoid", "nn-tanh", "nn-gelu", "nn-silu", "nn-elu", "nn-softmax", "nn-embedding", "nn-dropout", "nn-conv", "nn-maxpool", "nn-batchnorm", "nn-mse", "nn-bce", "nn-huber", "nn-sgd", "nn-rmsprop", "nn-adam", "nn-backprop", "nn-xor", "nn-lamb", "nn-rnn", "nn-lstm", "nn-attention", "nn-positions", "nn-encoder", "nn-ppo", "wars", "tri-game-tick", "tri-game-vault", "perf2-knockouts", "race-the-bee", "gatle", "tri-blog-list", "tri-game-selftest"]; +pub const WIDGET_KINDS : [279]str = ["cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "player", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "player", "player", "player", "cast", "cast", "tool", "tool", "cast", "player", "cast", "player", "cast", "player", "cast", "player", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "cast", "cast", "cast", "cast", "cast", "cast", "cast", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tool", "tab", "cast", "cast", "cast", "tool", "tool", "cast", "cast"]; +pub const WIDGET_CATEGORIES : [279]str = ["fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "fpga", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "compiler", "game", "game", "game", "game", "game", "game", "game", "game"]; +pub const WIDGET_PAGES : [279]str = ["term/x7-board/", "term/tri-x7-fasm/", "term/tri-x7-mutate/", "term/perf2-loop/", "term/tri-fpga-rgmii/", "term/tri-fpga-jtag/", "term/tri-fpga-pins/", "term/devkit-flow/", "play/hello-world/verilog/", "widgets/bit-diff/", "widgets/build-receipt/", "widgets/cost-curves/", "widgets/gf16-calc/", "widgets/idcode/", "widgets/lut-explain/", "widgets/pin-map/", "widgets/placement-map/", "widgets/resource-bars/", "widgets/slack-waterfall/", "widgets/test-waves/", "widgets/synth-smells/", "widgets/bit-autopsy/", "widgets/fasm-skyline/", "widgets/vcd-wrapped/", "widgets/fits-on/", "widgets/stat-card/", "widgets/lut-depth/", "widgets/fsm-sketch/", "widgets/lut-treemap/", "widgets/t27-cell/", "widgets/t27-vs-nvfp4/", "widgets/uart-bucket/", "term/tri-fpga-specs/", "term/tri-fpga-tools/", "term/tri-fpga-wire/", "term/tri-fpga-batch/", "term/tri-fpga-status/", "term/tri-fpga-tmpcheck/", "term/tri-fpga-keycheck/", "term/tri-fpga-selftest/", "term/tri-x7-refs/", "term/tri-x7-audit/", "term/t27c-clock-domain/", "term/t27c-clocks/", "term/t27c-wukong-v1/", "term/t27c-cts/", "term/t27c-mmcm/", "term/t27c-mmcm-mutate/", "term/t27c-timing/", "term/t27c-reset-sync/", "term/t27c-reset-sync-gen/", "term/t27c-mtbf/", "term/t27c-clock-domain-gen/", "term/t27c-fifo/", "term/t27c-fifo-mutate/", "term/t27c-fifo-flags/", "term/t27c-emitter-xdc/", "term/t27c-fpga-rxcap/", "term/t27-tri-competitors/", "term/t27-tri-discard/", "term/tri-fpga-txhold/", "term/tri-fpga-rxcap/", "term/tri-fpga-rxer/", "term/tri-fpga-steps/", "term/tri-fpga-ioclients/", "term/tri-fpga-claim/", "term/tri-fpga-release/", "term/tri-fpga-next/", "term/t27c-memory/", "term/t27c-spi-tb/", "term/t27c-check-uart/", "term/t27c-check-spi/", "term/t27c-check-apb/", "term/t27c-check-axi4/", "term/t27c-check-bridge/", "term/t27c-check-memory/", "term/t27c-verilog-uart/", "term/t27c-verilog-spi/", "term/t27c-verilog-apb/", "term/t27c-verilog-axi4/", "term/t27c-verilog-bridge/", "term/t27c-verilog-top/", "term/t27c-verilog-uart-tb/", "term/t27c-verilog-apb-tb/", "term/t27c-verilog-axi-tb/", "term/t27c-verilog-mem-tb/", "term/t27c-verilog-integration-tb/", "term/t27c-verilog-top-tb/", "term/t27c-verilog-spi-tb/", "term/t27c-hir-uart/", "term/t27c-hir-apb/", "term/t27c-hir-axi4/", "term/t27c-eth-crc/", "term/t27c-rgmii/", "widgets/jtag-verdict/", "widgets/line-bounce/", "widgets/eye-isi/", "widgets/ecc-secded/", "widgets/carry-chain/", "widgets/prefix-adder/", "widgets/csa-tree/", "widgets/shift-add/", "widgets/booth-radix4/", "widgets/dsp-fit/", "widgets/q-format/", "widgets/round-sat/", "widgets/sqnr/", "widgets/cordic/", "widgets/cordic-vector/", "widgets/sine-table/", "widgets/alias-fold/", "widgets/nco/", "widgets/dft-bin/", "widgets/fir-response/", "widgets/fir-design/", "widgets/fir-cost/", "widgets/decimator/", "widgets/cic-growth/", "widgets/polyphase/", "widgets/fft-butterfly/", "widgets/bit-reverse/", "widgets/fft-scaling/", "widgets/barker-corr/", "widgets/fir-fit/", "widgets/fir-on-board/", "play/hello-world/", "play/hello-world/rust/", "play/hello-world/js/", "term/t27c-hello-world/", "term/t27-tri-misread/", "widgets/test-touch/", "widgets/t27c-stages/", "term/t27c-e8m0/", "play/e8m0/", "term/t27c-ocp-mx/", "play/gfternary/", "term/t27c-gfternary/", "play/golden-sieve/", "term/t27c-golden-sieve/", "play/tnf17/", "term/t27c-tnf17/", "term/t27c-activation-quantizer/", "term/t27c-bitnet-majority/", "term/t27c-bitnet-neuron-nchunk/", "term/t27c-comb-ternary-dot/", "term/t27c-stream-ternary-mac/", "term/t27c-bitnet-mlp/", "term/t27c-gft-smul/", "term/t27c-gft-sadd/", "term/t27c-gft-signed-mac/", "term/t27c-gft-relu/", "term/t27c-gft-exp2/", "term/t27c-gft-argmax4/", "term/t27c-gft-nll/", "term/t27c-gft-sgd-step/", "term/t27c-gft-xornet/", "widgets/basics-what-a-spec-is/", "widgets/basics-the-module-line/", "widgets/basics-comments-and-prose/", "widgets/basics-constants/", "widgets/basics-whole-numbers/", "widgets/basics-true-false-and-text/", "widgets/basics-arrays/", "widgets/basics-trits/", "widgets/basics-expressions/", "widgets/basics-a-test-block/", "widgets/basics-many-tests/", "widgets/basics-functions/", "widgets/basics-local-names/", "widgets/basics-if-and-else/", "widgets/basics-loops/", "widgets/basics-pub-or-private/", "widgets/basics-structs/", "widgets/basics-enums/", "widgets/basics-use-other-modules/", "widgets/basics-invariants/", "widgets/basics-gen-ts/", "widgets/basics-seven-backends/", "widgets/basics-stages-of-t27c/", "widgets/basics-tri-commands/", "widgets/basics-reading-errors/", "widgets/basics-a-small-program/", "widgets/basics-where-next/", "widgets/golden-split/", "widgets/golden-phi-ratio/", "widgets/golden-lucas/", "widgets/golden-split-optimality/", "widgets/golden-radix-economy/", "widgets/golden-phi-in-gf16/", "widgets/golden-gf4/", "widgets/golden-gf6/", "widgets/golden-gf8/", "widgets/golden-gf10/", "widgets/golden-gf12/", "widgets/golden-gf14/", "widgets/golden-gf16/", "widgets/golden-dot-two/", "widgets/golden-gf24/", "widgets/golden-gf32/", "widgets/golden-gf48/", "widgets/golden-gf64/", "widgets/golden-gf96/", "widgets/golden-gf128/", "widgets/golden-gf256/", "widgets/golden-gf512/", "widgets/golden-gf1024/", "widgets/golden-gft8/", "widgets/golden-gft16/", "widgets/golden-gft32/", "widgets/golden-decode/", "term/t27-tri-vectors/", "term/t27-tri-census/", "term/t27-tri-seals/", "term/t27-tri-prose/", "term/t27-tri-lean/", "term/tri-selftest/", "term/play-terminal-gates/", "widgets/tc-why-three/", "widgets/tc-balanced-count/", "widgets/tc-flip-and-cut/", "widgets/tc-kleene-gates/", "widgets/tc-consensus-any/", "widgets/tc-sum-and-carry/", "widgets/tc-half-adder/", "widgets/tc-full-adder/", "widgets/tc-ripple-carry/", "widgets/tc-times-a-trit/", "widgets/tc-long-multiply/", "widgets/tc-ternary-mac/", "widgets/tc-two-bits/", "widgets/tc-five-in-a-byte/", "widgets/tc-trit-word/", "widgets/tc-instruction-word/", "widgets/tc-opcode-map/", "widgets/tc-immediate/", "widgets/tc-ternary-alu/", "widgets/tc-three-way-jump/", "widgets/tc-run-a-program/", "widgets/tc-compare/", "widgets/tc-thirds/", "widgets/tc-sort-three/", "widgets/tc-one-neuron/", "widgets/tc-detector/", "widgets/tc-tiny-layer/", "widgets/nn-relu/", "widgets/nn-sigmoid/", "widgets/nn-tanh/", "widgets/nn-gelu/", "widgets/nn-silu/", "widgets/nn-elu/", "widgets/nn-softmax/", "widgets/nn-embedding/", "widgets/nn-dropout/", "widgets/nn-conv/", "widgets/nn-maxpool/", "widgets/nn-batchnorm/", "widgets/nn-mse/", "widgets/nn-bce/", "widgets/nn-huber/", "widgets/nn-sgd/", "widgets/nn-rmsprop/", "widgets/nn-adam/", "widgets/nn-backprop/", "widgets/nn-xor/", "widgets/nn-lamb/", "widgets/nn-rnn/", "widgets/nn-lstm/", "widgets/nn-attention/", "widgets/nn-positions/", "widgets/nn-encoder/", "widgets/nn-ppo/", "wars", "term/tri-game-tick/", "term/tri-game-vault/", "term/perf2-knockouts/", "widgets/race-the-bee/", "widgets/gatle/", "term/tri-blog-list/", "term/tri-game-selftest/"]; +pub const WIDGET_TITLES : [279]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "WARS: agent configurations compared on real GitHub issues", "", "", "", "", "", "", ""]; +pub const WIDGET_LINES : [279]str = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "One issue, one pinned commit, the same tools and gates; only the decision layer changes, and a missing run stays unknown.", "", "", "", "", "", "", ""]; ; Why a person would pass this one on: the reason the widget is in the gallery at all. -pub const WIDGET_HOOKS : [252]str = ["The bitstream is byte-identical to openXC7's and runs on a real board: the claim most FPGA people doubt, shown.", "A Xilinx 7-series bitstream assembled with no Vivado anywhere in the path.", "Plant a bug in the bitstream path and watch the tests catch it: mutation testing for hardware.", "Place and route to a loaded bitstream, with the clock on screen.", "RGMII hold margins read from nextpnr's own SDF, not from a datasheet.", "The cable asks which chip is there and the chip answers with its IDCODE.", "Before an edit to a Verilog file: every spec and generator it would touch.", "The whole FPGA flow, one layer per line, from spec to board.", "A spec turned into Verilog inside a post, with the RTL read the way a hardware engineer reads it.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "17 of 17 conformance specs compile, their test blocks pass, and no generated file has drifted.", "14 of 14 bench tools pass their own self-tests in one sweep: decode 18/18, repin 17/17, firelog 10/10, tmpcheck 9/9, stamps 9/9, keep 9/9.", "Requested 115,200 puts 115,385 on the wire (+0.16 %), 921,600 puts 923,077, and 3,000,000 is exact.", "26 checks, no board, no RTL: every receipt returns, 11 loss and fault cases recover, and a lie stops the run.", "One command reads the bench: cables, locks, and the last board runs: three x7-board runs PASS 51840/51840.", "112 files under /tmp pinned by sha256 in specs: every one has a kept copy, 0 lost, 0 unlocated.", "84 board and model logs scanned for the TRI-NET key: 0 hits, 0 logs of 1 MB or more.", "16 spec-named scripts run their own --self-test, 0 bad; 8 without the flag are listed, not skipped silently.", "The part table in far.t27 matches prjxray-db part.json, all 6 reference bitstreams present, bitwalk reads all 6 in 84.4 ms.", "One command re-runs every sweep: CRC 12/12, ECC 32520/32520 frames, 82/82 pins, 4224/4224 segbits, gold 5/5. audit: CLEAN.", "The CDC spec through the real compiler: 12 tests pass natively and the header says what the model does and does not claim.", "The tri clocks card as a spec: constants a tool page reads, and a native test-report that says so plainly -- 0 tests, because it is not a test suite.", "The board itself as a spec: 15 tests pass natively and the part line names the xc7a200tfgg676 the Wukong carries.", "Clock-tree synthesis in numbers: 15 tests pass natively, and the header pins the Artix-7 teaching delays the tree arithmetic uses.", "The MMCM model through the real compiler: VCO window, M/D/O ranges, fractional multiply in eighths, the 1/56 phase step, 16 tests natively.", "Widen the VCO window with one sed and exactly one test objects -- the rejection test that names the 500 MHz config it calls out.", "Static timing as arithmetic: 25 tests pass natively on arcs, slack and Fmax, with the Artix-7 teaching delays in the header.", "The three reset kinds through the real compiler: async assert with sync release through 2 to 4 flops, and the racy async release, 16 tests natively.", "What the compiler emits for the reset pipe: t27c gen prints the Zig, one struct copy per clock, and wc -l counts it.", "Metastability MTBF without floats: the WP323 form in Q10 log2, one flop negative slack, two flops astronomical, 15 tests natively.", "The CDC model as Zig: t27c gen prints what it compiled and wc -l says how many lines of code the model is.", "The FIFO stdlib through the real compiler: 18 tests pass natively and 6 invariants are proved comptime.", "Move a pointer by 3 instead of 1 and every test still passes: the suite asserts fill and flags, never pointer values.", "Flip one flag assignment and a single test objects: the guard that keeps the FIFO honest.", "The pins-to-XDC emitter spec parsed by the real compiler, and the create_clock lines it exists to write.", "The fpga-rxcap tool card as a spec: constants for a tool page, and a native run that says 0 tests and why.", "168 records: 14 papers entered twice, 141 cite no score, 144 state zero at pass@1.", "67 specs lose 23,578 tokens to parser recovery, each held at its pinned bound.", "Smallest hold 3445 ps on TXD1 against a 1000 ps bench; each TX pin setup and hold from the routed SDF.", "Per-bit setup and hold of an async RX nibble against its RXC edge, from the routed SDF: one nibble changes 2387 to 2486 ps apart, so a binary counter tears where a gray one cannot.", "RX_ER pulses injected at exact nibble positions of a ping -- preamble, mid-frame, IP header -- and the frame state each pulse leaves behind, RTL vs model.", "The Ethernet bring-up plan on the bench: pre-registered steps, logged exits, what ran and what did not.", "The registered IO clients on the bench, read live: names, claims and what each declares it owns.", "The bench claim in action: one client takes the hardware lock and the tool reports who holds it.", "The bench lock given back: the client gives up its claim and the bench reports itself free.", "The next queued step on the bench, read live from the run state.", "The memory map spec through the real compiler: 15 tests pass natively and 6 invariants are proved comptime.", "The SPI testbench through the real compiler: 7 tests pass natively, driving the modes and checking the captures.", "t27c check on the UART spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the SPI spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the APB bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the AXI4 spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the bus bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the memory spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "The UART spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The SPI spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The APB bridge spec lowered to synthesizable Verilog: port list, PSEL and PENABLE wiring, the address decode.", "The AXI4 spec lowered to synthesizable Verilog: the five channels' wiring and handshakes as generated wires.", "The bus bridge spec lowered to synthesizable Verilog: both sides of the crossing as generated wires.", "The whole design in one spec lowered to synthesizable Verilog: clocks, resets and bus wiring as the compiler emits them.", "The UART testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The APB bridge testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The AXI4 testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The memory testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The integration testbench spec lowered to Verilog: every bus of the design in one bench.", "The top-level testbench spec lowered to Verilog: the whole design under one bench.", "The SPI testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The UART spec lowered to hardware IR: the compiler's own view of the wires and state before Verilog exists.", "The APB bridge spec lowered to hardware IR: PSEL, PENABLE and the decode as the compiler structures them.", "The AXI4 spec lowered to hardware IR: the five channels and their handshakes as the compiler structures them.", "The Ethernet FCS spec through the real compiler: 8 tests pass natively -- the table derived from one bit step, the 0xCBF43926 check value, the 0xDEBB20E3 receiver residue.", "The RGMII spec through the real compiler: 7 tests pass natively and 1 invariant is proved comptime -- the 8 ns gigabit period, a nibble on both edges, the 78 ps tap ladder.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "The t27 compiler running as WebAssembly in a post: compile, test, seven backends.", "The same spec as Rust, printed by a terminal in the page.", "The only backend that runs in the browser: generate the module, then run it.", "t27c on hello_world.t27, on a real machine, every byte as printed.", "Code that compiles and is wrong: the tool that finds it.", "", "", "The OCP MX scale byte as a spec: 2^(e-127), code 255 is NaN, 18 tests and 9 comptime invariants, compiled on a real machine.", "The same scale byte compiled in your browser: seven backends, the spec's tests run in the page, and every skip says why.", "One outlier sets the scale for 32 weights: MXFP4 flushes 23 of them to zero, MXFP8 E4M3 none. 49 tests pass; a planted bug fails one.", "Ternary weights scaled by phi, compiled in your browser: codes 00, 01, 10, and the fourth code folded to zero.", "13 of 13 tests pass natively, and the report says 8 of them executed no assert; a planted bug fails exactly one.", "Five measured rules for a ternary weight alphabet, and the one formula that passes all five, run in your browser.", "One more trit and the spec does not compile at all: BLOCKED, not failed, because no test ever ran.", "A 17-bit float whose exponent is four balanced trits, 3^4 = 81 values, compiled in your browser.", "34 tests pass natively, none vacuous; swap one XOR for OR and only the test that negates twice fails.", "A neuron's sum squeezed back to one trit: 7 tests pass natively, and turning one > into >= fails only the boundary test.", "One ternary neuron, two functions picked by its weights: 12 tests pass natively, and one weight moved from P to Z fails exactly one.", "A neuron wider than 27 inputs, summed chunk by chunk: 11 tests pass natively, and a loop that stops after one chunk fails exactly one.", "A 27-lane ternary dot product as pure wires: 4 tests pass natively, and one wrong sign in tmul fails exactly one.", "The same dot product added into a register on every clock: 4 tests pass natively, and a lane mask short one bit fails exactly one.", "A whole small ternary network, 3 neurons then 2: 4 tests pass natively, and a trit packed one bit low fails exactly one.", "A signed multiply: 3 tests pass natively, none vacuous, and a sign stuck at 0 fails exactly one, m2.", "A signed add: 3 tests pass natively, and adding where opposite signs must subtract fails exactly one, a2.", "Two signed products summed: 4 tests pass natively, and OR in place of the sign XOR fails exactly one, pp.", "A ReLU: 4 tests pass natively, and letting negative inputs through fails only negz, the one test with a negative input.", "2^x for a softmax: 4 tests pass natively, and dropping the minus sign of k fails exactly one, em1.", "argmax by comparing bits alone: 4 tests pass natively, and >= in place of > fails exactly one, tie_low.", "A loss in bits: 3 tests pass natively, and a zero with the sign bit set fails exactly one, perfect.", "One SGD step: 3 tests pass natively, and g times g in place of eta times g fails exactly one, ascend.", "A 2-layer ReLU net for XOR: 4 tests pass natively, and one relu removed fails exactly one, x00.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "34 vector files, 512 cases: 2 files executed, 8 debt, 24 prose-only; 19% carry data.", "Four census populations recounted another way all agree; three are named as uncheckable.", "31 of 1,428 seals record no output (16 specs); 3 of those are missing from the debt ledger.", "11 specs refused at parse, 0 blocked only by prose, 23 broken on purpose as fixtures.", "12 Lean files, 15,553 lines and 4 sorry, are reached by no build root: nothing compiles them.", "tri, railway, python3 and the loop directory: each present or not, in one call.", "The terminal for seven t27 backends: every command run on hello_world. 21 pass, 0 fail.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Pick a lane and see whether the TRI decision layer beats the baseline on the same issue.", "One tick of the Queen's loop: an anomaly scan that reports only what changed.", "The loop's skills checked against snapshots before an agent may use them.", "Three performance bits, and one knockout bitstream per bit to prove each one matters.", "", "", "73 published posts with date, language and revision, newest first.", "6 of 6 self-tests hold: anomalies, blog_drift, lessons, site_gate, tick, vault."]; +pub const WIDGET_HOOKS : [279]str = ["The bitstream is byte-identical to openXC7's and runs on a real board: the claim most FPGA people doubt, shown.", "A Xilinx 7-series bitstream assembled with no Vivado anywhere in the path.", "Plant a bug in the bitstream path and watch the tests catch it: mutation testing for hardware.", "Place and route to a loaded bitstream, with the clock on screen.", "RGMII hold margins read from nextpnr's own SDF, not from a datasheet.", "The cable asks which chip is there and the chip answers with its IDCODE.", "Before an edit to a Verilog file: every spec and generator it would touch.", "The whole FPGA flow, one layer per line, from spec to board.", "A spec turned into Verilog inside a post, with the RTL read the way a hardware engineer reads it.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "17 of 17 conformance specs compile, their test blocks pass, and no generated file has drifted.", "14 of 14 bench tools pass their own self-tests in one sweep: decode 18/18, repin 17/17, firelog 10/10, tmpcheck 9/9, stamps 9/9, keep 9/9.", "Requested 115,200 puts 115,385 on the wire (+0.16 %), 921,600 puts 923,077, and 3,000,000 is exact.", "26 checks, no board, no RTL: every receipt returns, 11 loss and fault cases recover, and a lie stops the run.", "One command reads the bench: cables, locks, and the last board runs: three x7-board runs PASS 51840/51840.", "112 files under /tmp pinned by sha256 in specs: every one has a kept copy, 0 lost, 0 unlocated.", "84 board and model logs scanned for the TRI-NET key: 0 hits, 0 logs of 1 MB or more.", "16 spec-named scripts run their own --self-test, 0 bad; 8 without the flag are listed, not skipped silently.", "The part table in far.t27 matches prjxray-db part.json, all 6 reference bitstreams present, bitwalk reads all 6 in 84.4 ms.", "One command re-runs every sweep: CRC 12/12, ECC 32520/32520 frames, 82/82 pins, 4224/4224 segbits, gold 5/5. audit: CLEAN.", "The CDC spec through the real compiler: 12 tests pass natively and the header says what the model does and does not claim.", "The tri clocks card as a spec: constants a tool page reads, and a native test-report that says so plainly -- 0 tests, because it is not a test suite.", "The board itself as a spec: 15 tests pass natively and the part line names the xc7a200tfgg676 the Wukong carries.", "Clock-tree synthesis in numbers: 15 tests pass natively, and the header pins the Artix-7 teaching delays the tree arithmetic uses.", "The MMCM model through the real compiler: VCO window, M/D/O ranges, fractional multiply in eighths, the 1/56 phase step, 16 tests natively.", "Widen the VCO window with one sed and exactly one test objects -- the rejection test that names the 500 MHz config it calls out.", "Static timing as arithmetic: 25 tests pass natively on arcs, slack and Fmax, with the Artix-7 teaching delays in the header.", "The three reset kinds through the real compiler: async assert with sync release through 2 to 4 flops, and the racy async release, 16 tests natively.", "What the compiler emits for the reset pipe: t27c gen prints the Zig, one struct copy per clock, and wc -l counts it.", "Metastability MTBF without floats: the WP323 form in Q10 log2, one flop negative slack, two flops astronomical, 15 tests natively.", "The CDC model as Zig: t27c gen prints what it compiled and wc -l says how many lines of code the model is.", "The FIFO stdlib through the real compiler: 18 tests pass natively and 6 invariants are proved comptime.", "Move a pointer by 3 instead of 1 and every test still passes: the suite asserts fill and flags, never pointer values.", "Flip one flag assignment and a single test objects: the guard that keeps the FIFO honest.", "The pins-to-XDC emitter spec parsed by the real compiler, and the create_clock lines it exists to write.", "The fpga-rxcap tool card as a spec: constants for a tool page, and a native run that says 0 tests and why.", "168 records: 14 papers entered twice, 141 cite no score, 144 state zero at pass@1.", "67 specs lose 23,578 tokens to parser recovery, each held at its pinned bound.", "Smallest hold 3445 ps on TXD1 against a 1000 ps bench; each TX pin setup and hold from the routed SDF.", "Per-bit setup and hold of an async RX nibble against its RXC edge, from the routed SDF: one nibble changes 2387 to 2486 ps apart, so a binary counter tears where a gray one cannot.", "RX_ER pulses injected at exact nibble positions of a ping -- preamble, mid-frame, IP header -- and the frame state each pulse leaves behind, RTL vs model.", "The Ethernet bring-up plan on the bench: pre-registered steps, logged exits, what ran and what did not.", "The registered IO clients on the bench, read live: names, claims and what each declares it owns.", "The bench claim in action: one client takes the hardware lock and the tool reports who holds it.", "The bench lock given back: the client gives up its claim and the bench reports itself free.", "The next queued step on the bench, read live from the run state.", "The memory map spec through the real compiler: 15 tests pass natively and 6 invariants are proved comptime.", "The SPI testbench through the real compiler: 7 tests pass natively, driving the modes and checking the captures.", "t27c check on the UART spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the SPI spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the APB bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the AXI4 spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the bus bridge spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "t27c check on the memory spec: 0 errors, 0 warnings -- the first bar every lesson's spec clears.", "The UART spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The SPI spec lowered to synthesizable Verilog: the TRINITY banner, the module port list and the datapath as wires.", "The APB bridge spec lowered to synthesizable Verilog: port list, PSEL and PENABLE wiring, the address decode.", "The AXI4 spec lowered to synthesizable Verilog: the five channels' wiring and handshakes as generated wires.", "The bus bridge spec lowered to synthesizable Verilog: both sides of the crossing as generated wires.", "The whole design in one spec lowered to synthesizable Verilog: clocks, resets and bus wiring as the compiler emits them.", "The UART testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The APB bridge testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The AXI4 testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The memory testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The integration testbench spec lowered to Verilog: every bus of the design in one bench.", "The top-level testbench spec lowered to Verilog: the whole design under one bench.", "The SPI testbench spec lowered to Verilog: what a bench looks like when the compiler emits it.", "The UART spec lowered to hardware IR: the compiler's own view of the wires and state before Verilog exists.", "The APB bridge spec lowered to hardware IR: PSEL, PENABLE and the decode as the compiler structures them.", "The AXI4 spec lowered to hardware IR: the five channels and their handshakes as the compiler structures them.", "The Ethernet FCS spec through the real compiler: 8 tests pass natively -- the table derived from one bit step, the 0xCBF43926 check value, the 0xDEBB20E3 receiver residue.", "The RGMII spec through the real compiler: 7 tests pass natively and 1 invariant is proved comptime -- the 8 ns gigabit period, a nibble on both edges, the 78 ps tap ladder.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "The t27 compiler running as WebAssembly in a post: compile, test, seven backends.", "The same spec as Rust, printed by a terminal in the page.", "The only backend that runs in the browser: generate the module, then run it.", "t27c on hello_world.t27, on a real machine, every byte as printed.", "Code that compiles and is wrong: the tool that finds it.", "", "", "The OCP MX scale byte as a spec: 2^(e-127), code 255 is NaN, 18 tests and 9 comptime invariants, compiled on a real machine.", "The same scale byte compiled in your browser: seven backends, the spec's tests run in the page, and every skip says why.", "One outlier sets the scale for 32 weights: MXFP4 flushes 23 of them to zero, MXFP8 E4M3 none. 49 tests pass; a planted bug fails one.", "Ternary weights scaled by phi, compiled in your browser: codes 00, 01, 10, and the fourth code folded to zero.", "13 of 13 tests pass natively, and the report says 8 of them executed no assert; a planted bug fails exactly one.", "Five measured rules for a ternary weight alphabet, and the one formula that passes all five, run in your browser.", "One more trit and the spec does not compile at all: BLOCKED, not failed, because no test ever ran.", "A 17-bit float whose exponent is four balanced trits, 3^4 = 81 values, compiled in your browser.", "34 tests pass natively, none vacuous; swap one XOR for OR and only the test that negates twice fails.", "A neuron's sum squeezed back to one trit: 7 tests pass natively, and turning one > into >= fails only the boundary test.", "One ternary neuron, two functions picked by its weights: 12 tests pass natively, and one weight moved from P to Z fails exactly one.", "A neuron wider than 27 inputs, summed chunk by chunk: 11 tests pass natively, and a loop that stops after one chunk fails exactly one.", "A 27-lane ternary dot product as pure wires: 4 tests pass natively, and one wrong sign in tmul fails exactly one.", "The same dot product added into a register on every clock: 4 tests pass natively, and a lane mask short one bit fails exactly one.", "A whole small ternary network, 3 neurons then 2: 4 tests pass natively, and a trit packed one bit low fails exactly one.", "A signed multiply: 3 tests pass natively, none vacuous, and a sign stuck at 0 fails exactly one, m2.", "A signed add: 3 tests pass natively, and adding where opposite signs must subtract fails exactly one, a2.", "Two signed products summed: 4 tests pass natively, and OR in place of the sign XOR fails exactly one, pp.", "A ReLU: 4 tests pass natively, and letting negative inputs through fails only negz, the one test with a negative input.", "2^x for a softmax: 4 tests pass natively, and dropping the minus sign of k fails exactly one, em1.", "argmax by comparing bits alone: 4 tests pass natively, and >= in place of > fails exactly one, tie_low.", "A loss in bits: 3 tests pass natively, and a zero with the sign bit set fails exactly one, perfect.", "One SGD step: 3 tests pass natively, and g times g in place of eta times g fails exactly one, ascend.", "A 2-layer ReLU net for XOR: 4 tests pass natively, and one relu removed fails exactly one, x00.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "34 vector files, 512 cases: 2 files executed, 8 debt, 24 prose-only; 19% carry data.", "Four census populations recounted another way all agree; three are named as uncheckable.", "31 of 1,428 seals record no output (16 specs); 3 of those are missing from the debt ledger.", "11 specs refused at parse, 0 blocked only by prose, 23 broken on purpose as fixtures.", "12 Lean files, 15,553 lines and 4 sorry, are reached by no build root: nothing compiles them.", "tri, railway, python3 and the loop directory: each present or not, in one call.", "The terminal for seven t27 backends: every command run on hello_world. 21 pass, 0 fail.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Pick a lane and see whether the TRI decision layer beats the baseline on the same issue.", "One tick of the Queen's loop: an anomaly scan that reports only what changed.", "The loop's skills checked against snapshots before an agent may use them.", "Three performance bits, and one knockout bitstream per bit to prove each one matters.", "", "", "73 published posts with date, language and revision, newest first.", "6 of 6 self-tests hold: anomalies, blog_drift, lessons, site_gate, tick, vault."]; ; --- Ideas: asked for, not built --------------------------------------------------------------- ; From what engineers share today (gh-skyline, Tiny Tapeout renders, Wrapped cards, Gatle-style @@ -119,9 +119,9 @@ test the_fpga_shelf_comes_first_and_opens_on_the_board { } test the_arena_is_a_tab_and_says_its_own_words { - assert WIDGET_IDS[244] == "wars"; - assert WIDGET_KINDS[244] == "tab"; - assert WIDGET_PAGES[244] == "wars"; + assert WIDGET_IDS[271] == "wars"; + assert WIDGET_KINDS[271] == "tab"; + assert WIDGET_PAGES[271] == "wars"; } test the_gallery_posts_nothing { @@ -157,8 +157,8 @@ test the_verification_shelf_is_rehearsals_and_audits { test ideas_are_counted_apart_from_widgets { assert IDEA_COUNT == 6; - assert WIDGET_IDS[249] == "gatle"; - assert WIDGET_COUNT == 252; + assert WIDGET_IDS[276] == "gatle"; + assert WIDGET_COUNT == 279; } test the_ternary_machine_shelf_runs_before_the_arena { @@ -172,9 +172,9 @@ test every_tool_lives_under_widgets_and_keeps_its_words_on_its_page { assert WIDGET_KINDS[9] == "tool"; assert WIDGET_PAGES[9] == "widgets/bit-diff/"; assert WIDGET_HOOKS[9] == ""; - assert WIDGET_KINDS[248] == "tool"; - assert WIDGET_CATEGORIES[248] == "game"; - assert WIDGET_PAGES[248] == "widgets/race-the-bee/"; + assert WIDGET_KINDS[275] == "tool"; + assert WIDGET_CATEGORIES[275] == "game"; + assert WIDGET_PAGES[275] == "widgets/race-the-bee/"; } test the_arithmetic_shelf_closes_the_fpga_bench { @@ -185,3 +185,12 @@ test the_arithmetic_shelf_closes_the_fpga_bench { assert WIDGET_CATEGORIES[124] == "fpga"; assert WIDGET_HOOKS[124] == ""; } + +test the_neural_network_shelf_runs_before_the_arena { + assert WIDGET_IDS[244] == "nn-relu"; + assert WIDGET_KINDS[244] == "tool"; + assert WIDGET_PAGES[244] == "widgets/nn-relu/"; + assert WIDGET_IDS[270] == "nn-ppo"; + assert WIDGET_CATEGORIES[270] == "compiler"; + assert WIDGET_IDS[271] == "wars"; +} diff --git a/apps/website/specs/widgets/nn-adam.t27 b/apps/website/specs/widgets/nn-adam.t27 new file mode 100644 index 0000000000..df20f42a52 --- /dev/null +++ b/apps/website/specs/widgets/nn-adam.t27 @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-adam.t27 -- Adam: momentum, a running scale and the bias correction +; Source of truth for public/widgets/nn-adam/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-adam/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/adam.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 18 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets the number of steps and three gradients from -50 to 50. The path is +; descend(n) of the spec (lr 0.1 on (x - 3)^2 from 0); the bars and tiles are first_step(g0, g1, g2, +; which, i) on weights (1, 2, 3) at lr 0.001. + +; WHAT IT DOES NOT CLAIM: the bowl is one weight, as in the SGD lesson, so the two paths can be +; compared, not ranked. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_adam; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-adam"; +pub const TITLE : str = "Adam: the optimizer most networks are trained with"; +pub const DESCRIPTION : str = "Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size."; +pub const IMAGE_ALT : str = "Adam card: the green path rises from 0, passes the white dashed minimum at 3, peaks near 3.18 and settles at 3.00005 by step 200. Below, three bars of the first moment m read 0.20, -4.00 and 0.05 while the weights read 0.9990, 2.0010 and 2.9990. Tiles read x 3.00005 and step 1 at 0.1000."; +pub const HOOK : str = "Gradients 2, -40 and 0.5 all move their weights by exactly 0.001 on step 1. Adam reaches 3.00005 in 200 steps at lr 0.1."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/adam.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 18 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 200; +pub const K_MINIMUM : u8 = 3; +pub const K_Y_LO : u8 = 0; +pub const K_Y_HI : u8 = 4; +pub const K_Y_TICKS : [5]u8 = [0, 1, 2, 3, 4]; +pub const K_STEP_TICKS : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_G_LO_C : i16 = -5000; +pub const K_G_HI_C : u16 = 5000; +pub const K_BAR_LO : i8 = -5; +pub const K_BAR_HI : u8 = 5; +pub const K_BAR_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_PRESET_STEPS : [4]u8 = [200, 10, 50, 200]; +pub const K_PRESET_G0_C : [4]i16 = [200, 100, -100, 5000]; +pub const K_PRESET_G1_C : [4]i16 = [-4000, 100, -100, 1]; +pub const K_PRESET_G2_C : [4]i16 = [50, 100, -100, -5000]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["200 steps; g 2, -40, 0.5", "10 steps; equal g", "50 steps; negative g", "200 steps; g 50, 0.01, -50"]; +pub const SAY_ASK : str = "Why is Adam the optimizer most networks are trained with?"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_G : str = "gradient"; +pub const SAY_W : str = "w"; +pub const SAY_PLOT_LABEL : str = "The weight after every Adam step, from 0 toward the minimum at 3"; +pub const SAY_FIRST_LABEL : str = "Step 1 on weights 1, 2, 3: the first moment m and the weight after"; +pub const SAY_PATH : str = "Adam, lr 0.1"; +pub const SAY_MIN : str = "the minimum"; +pub const SAY_X_NOW : str = "x after the steps"; +pub const SAY_X_ONE : str = "after step 1"; +pub const SAY_W_AFTER : str = "weights after step 1"; +pub const SAY_V : str = "second moment v"; +pub const SAY_NOTE : str = "m and v start at zero, so early on they are too small; dividing by 1 - beta^t corrects them. On step 1 that makes m / sqrt(v) exactly the sign of the gradient."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/adam.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_gradients_are_symmetric { + assert K_G_LO_C + K_G_HI_C == 0; + assert K_PRESET_G0_C[3] == K_G_HI_C; + assert K_PRESET_G2_C[3] == K_G_LO_C; +} + +test the_minimum_is_inside_the_axis { + assert K_MINIMUM == 3; + assert K_Y_HI > K_MINIMUM; + assert K_PRESET_STEPS[0] == K_STEPS_HI; +} diff --git a/apps/website/specs/widgets/nn-attention.t27 b/apps/website/specs/widgets/nn-attention.t27 new file mode 100644 index 0000000000..32f3a9f038 --- /dev/null +++ b/apps/website/specs/widgets/nn-attention.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-attention.t27 -- scaled dot-product attention with two heads and a causal mask +; Source of truth for public/widgets/nn-attention/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-attention/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 24 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles the causal mask and taps a query row. Every weight is +; forward_at(causal, 1, i) and every output forward_at(causal, 0, i) of the spec: 3 positions, +; d_model 4, 2 heads, its own q, k and v. + +; WHAT IT DOES NOT CLAIM: q, k and v are the spec's fixture, not learned projections of real tokens. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_attention; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-attention"; +pub const TITLE : str = "Attention: how a word decides which other words to read"; +pub const DESCRIPTION : str = "Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future."; +pub const IMAGE_ALT : str = "Attention card, causal: two 3 x 3 grids in blue to white. Head 0 reads 1.000 / 0.452 0.548 / 0.230 0.321 0.449 with the upper triangle at 0; head 1 1.000 / 0.434 0.566 / 0.210 0.316 0.474. Row 2 is outlined. Below, a 3 x 4 output grid; position 2 outputs 0.59 0.69 0.81 0.91."; +pub const HOOK : str = "Causal: position 0 reads only itself (1.000), position 1 splits 0.45 / 0.55, position 2 spreads 0.23, 0.32, 0.45. Every row is a softmax."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/attention_mechanism.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 24 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SEQ : u8 = 3; +pub const K_D_MODEL : u8 = 4; +pub const K_HEADS : u8 = 2; +pub const K_PRESET_CAUSAL : [3]u8 = [1, 0, 1]; +pub const K_PRESET_Q : [3]u8 = [2, 2, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["Causal, position 2", "Full, position 2", "Causal, position 1"]; +pub const SAY_ASK : str = "How does a word decide which other words to read?"; +pub const SAY_CAUSAL : str = "causal mask"; +pub const SAY_HEAD : str = "head"; +pub const SAY_POS : str = "pos"; +pub const SAY_DIM : str = "dim"; +pub const SAY_ROWS : str = "rows are queries, columns keys"; +pub const SAY_TAP : str = "Tap a row to follow one query."; +pub const SAY_OUT_LABEL : str = "The output: each position's weighted average of the values"; +pub const SAY_MASK : str = "mask"; +pub const SAY_MASK_ON : str = "no reading ahead"; +pub const SAY_MASK_OFF : str = "every key"; +pub const SAY_OUT_ROW : str = "output of {0}"; +pub const SAY_NOTE : str = "Each weight is softmax(q . k / sqrt(d)) over the keys of its row; the output is the values averaged by those weights. Two heads look at different halves of the vector."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/attention_mechanism.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test two_heads_split_the_model { + assert K_HEADS * 2 == K_D_MODEL; + assert K_SEQ == 3; +} + +test the_presets_stay_in_range { + assert K_PRESET_Q[0] < K_SEQ; + assert K_PRESET_CAUSAL[0] == 1; + assert K_PRESET_CAUSAL[1] == 0; +} diff --git a/apps/website/specs/widgets/nn-backprop.t27 b/apps/website/specs/widgets/nn-backprop.t27 new file mode 100644 index 0000000000..9b1fde1101 --- /dev/null +++ b/apps/website/specs/widgets/nn-backprop.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-backprop.t27 -- backpropagation through one dense layer +; Source of truth for public/widgets/nn-backprop/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-backprop/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/dense_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 19 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets the output gradients g0 and g1 from -2 to 2. Edges are +; backward_at(g0, g1, 1, o * 3 + i), input nodes backward_at(g0, g1, 0, i), bias tiles +; backward_at(g0, g1, 2, o), and the loss loss_at = g . y at x and at x with x0 moved by 1. + +; WHAT IT DOES NOT CLAIM: the layer is the spec's fixture (W = [[1, 2, 3], [-1, 0, 1]], b = (0.5, +; -0.5)), linear; the inputs are repeated as K_X. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_backprop; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-backprop"; +pub const TITLE : str = "Backpropagation: how blame flows back through a layer"; +pub const DESCRIPTION : str = "Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers."; +pub const IMAGE_ALT : str = "Backprop card: a dense layer of 3 inputs and 2 outputs with g = (1, 0.5). Six edges are coloured by their weight gradients 1, 2, 3 and 0.5, 1, 1.5; the input nodes hold 0.5, 2.0 and 3.5. Tiles read input gradients 0.50 2.00 3.50, bias gradients 1.00 0.50, loss 15.250 and with x0 moved by 1 15.750."; +pub const HOOK : str = "With g = (1, 0.5) on inputs (1, 2, 3), the weights get 1, 2, 3 and 0.5, 1, 1.5, and the inputs get 0.5, 2, 3.5. Two products are the whole rule."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/dense_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 19 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X : [3]u8 = [1, 2, 3]; +pub const K_X_NUDGED : [3]u8 = [2, 2, 3]; +pub const K_G_LO_C : i16 = -200; +pub const K_G_HI_C : u16 = 200; +pub const K_PRESET_G0_C : [4]i16 = [100, 100, 0, -200]; +pub const K_PRESET_G1_C : [4]i16 = [50, 0, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["g = (1, 0.5)", "Only output 0", "Only output 1", "g = (-2, 1)"]; +pub const SAY_ASK : str = "How does blame for an error flow back through a layer?"; +pub const SAY_G : str = "g"; +pub const SAY_NET_LABEL : str = "Three inputs, two outputs; edges coloured by their weight gradient, inputs by theirs"; +pub const SAY_NET_CAP : str = "Edge label: g_o x_i. Input node: sum over o of W[o][i] g_o. Pink is negative, green positive."; +pub const SAY_GRAD_IN : str = "input gradients"; +pub const SAY_GRAD_B : str = "bias gradients"; +pub const SAY_LOSS : str = "loss g . y"; +pub const SAY_LOSS_NUDGED : str = "with x0 + 1"; +pub const SAY_NOTE : str = "The layer is linear, so moving x0 by 1 moves the loss by exactly its input gradient: compare the last two tiles. Chain this rule layer by layer and you have backpropagation."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/dense_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_inputs_are_the_spec_fixture { + assert K_X[0] == 1; + assert K_X[2] == 3; + assert K_X_NUDGED[0] == K_X[0] + 1; + assert K_X_NUDGED[2] == K_X[2]; +} + +test the_presets_stay_in_range { + assert K_PRESET_G0_C[3] == K_G_LO_C; + assert K_PRESET_G1_C[2] <= K_G_HI_C; + assert K_G_LO_C + K_G_HI_C == 0; +} diff --git a/apps/website/specs/widgets/nn-batchnorm.t27 b/apps/website/specs/widgets/nn-batchnorm.t27 new file mode 100644 index 0000000000..5c886e03c8 --- /dev/null +++ b/apps/website/specs/widgets/nn-batchnorm.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-batchnorm.t27 -- batch normalisation: features on different scales, made comparable +; Source of truth for public/widgets/nn-batchnorm/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-batchnorm/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/batchnorm_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 12 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader reads the batch before and after and sets gamma and the running +; statistics. The normalised batch is train_at(b, f) and the inference bars forward_at(gamma, +; shifted, i) on inputs (1, 2, 3), beta 0.25. + +; WHAT IT DOES NOT CLAIM: the batch on the left is the spec's fixture, repeated as K_BATCH; the +; normalised values come from the compiled fn. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_batchnorm; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-batchnorm"; +pub const TITLE : str = "Batch norm: features on very different scales, made comparable"; +pub const DESCRIPTION : str = "A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference."; +pub const IMAGE_ALT : str = "Batch-norm card: on the left the spec's batch, 4 samples by 3 features (1, 2, 3, 4 / 10, 20, 30, 40 / -1, -1, 1, 1); on the right the normalised batch, the first two columns both -1.34, -0.45, 0.45, 1.34 and the third -1.00, -1.00, 1.00, 1.00. Below, gamma 1 at inference gives 1.25, 2.25, 3.25."; +pub const HOOK : str = "Features 1..4 and 10..40 come out identical, -1.34, -0.45, 0.45, 1.34: batch norm keeps the shape of each feature and throws away its scale."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/batchnorm_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 12 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_BATCH_ROWS : u8 = 4; +pub const K_FEATURES : u8 = 3; +pub const K_BATCH : [12]i8 = [1, 10, -1, 2, 20, -1, 3, 30, 1, 4, 40, 1]; +pub const K_GAMMA_HI_C : u16 = 300; +pub const K_INFER_INPUT : [3]u8 = [1, 2, 3]; +pub const K_BAR_LO_C : i16 = -200; +pub const K_BAR_HI_C : u16 = 1000; +pub const K_BAR_TICKS : [5]i8 = [-2, 0, 2, 5, 10]; +pub const K_PRESET_GAMMA_C : [4]u16 = [100, 200, 100, 50]; +pub const K_PRESET_SHIFTED : [4]u8 = [0, 0, 1, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["gamma 1, mean 0 / var 1", "gamma 2", "gamma 1, mean 2 / var 4", "gamma 0.5, mean 2 / var 4"]; +pub const SAY_ASK : str = "What happens when one feature is ten times larger than another?"; +pub const SAY_GAMMA : str = "gamma"; +pub const SAY_SHIFTED : str = "running mean 2, variance 4"; +pub const SAY_BEFORE_LABEL : str = "The batch: 4 samples x 3 features"; +pub const SAY_AFTER_LABEL : str = "After batch norm"; +pub const SAY_INFER_LABEL : str = "At inference: inputs 1, 2, 3 through the running statistics"; +pub const SAY_FEATURE : str = "feature"; +pub const SAY_SAMPLE : str = "sample"; +pub const SAY_INPUT : str = "input"; +pub const SAY_COL : str = "feature {0} after"; +pub const SAY_INFER : str = "inference out"; +pub const SAY_NOTE : str = "Training normalises with the batch's own mean and variance; inference cannot, so it uses running averages kept during training. gamma and beta are learned, so the layer can undo the normalisation where that helps."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/batchnorm_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_batch_is_the_spec_fixture { + assert K_BATCH_ROWS * K_FEATURES == 12; + assert K_BATCH[1] == 10; + assert K_BATCH[10] == 40; + assert K_BATCH[2] + 1 == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_GAMMA_C[1] <= K_GAMMA_HI_C; + assert K_PRESET_SHIFTED[2] == 1; + assert K_INFER_INPUT[2] == 3; +} diff --git a/apps/website/specs/widgets/nn-bce.t27 b/apps/website/specs/widgets/nn-bce.t27 new file mode 100644 index 0000000000..c1f2b414ae --- /dev/null +++ b/apps/website/specs/widgets/nn-bce.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-bce.t27 -- binary cross-entropy: why a confident wrong answer costs so much +; Source of truth for public/widgets/nn-bce/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-bce/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 14 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader moves three probabilities from 0.01 to 0.99. The loss is loss_of(a, b, c, +; false) against the spec's targets (1, 0, 1), the bars grad_of, and the curve loss_of over the +; first prediction; one tile feeds logits of 0 through the spec's sigmoid. + +; WHAT IT DOES NOT CLAIM: the spec clips each probability to [1e-7, 1 - 1e-7], so the curve is +; finite at the ends of this window. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_bce; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-bce"; +pub const TITLE : str = "Cross-entropy: why a confident wrong answer costs so much"; +pub const DESCRIPTION : str = "Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound."; +pub const IMAGE_ALT : str = "Cross-entropy card: predictions 0.8, 0.3 and 0.9 against targets 1, 0, 1. A red curve shows the loss as prediction 0 runs from 0.01 to 0.99, rising steeply on the left, with the cursor at 0.8; gradient bars read -1.25, 1.43 and -1.11. Tiles read loss 0.2284, sure and right 0.0101, sure and wrong 4.6052, logits at 0 giving 0.6931."; +pub const HOOK : str = "Predicting 0.99 where the answer is 1 costs 0.01; predicting 0.01 costs 4.6. The cost of a confident mistake is what trains a classifier."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/binary_crossentropy_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 14 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_TARGETS : [3]u8 = [1, 0, 1]; +pub const K_P_LO_C : u8 = 1; +pub const K_P_HI_C : u8 = 99; +pub const K_X_TICKS_C : [5]u8 = [1, 25, 50, 75, 99]; +pub const K_LOSS_HI_C : u16 = 200; +pub const K_LOSS_TICKS_C : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_GRAD_LO_C : i16 = -1000; +pub const K_GRAD_HI_C : u16 = 1000; +pub const K_GRAD_TICKS : [5]i8 = [-10, -5, 0, 5, 10]; +pub const K_PRESET_A_C : [4]u8 = [80, 99, 10, 50]; +pub const K_PRESET_B_C : [4]u8 = [30, 1, 90, 50]; +pub const K_PRESET_C_C : [4]u8 = [90, 99, 10, 50]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["0.8, 0.3, 0.9", "Sure and right", "Sure and wrong", "Undecided"]; +pub const SAY_ASK : str = "Why does a confident wrong answer cost so much?"; +pub const SAY_PRED : str = "p"; +pub const SAY_TARGET : str = "answer"; +pub const SAY_CURVE_LABEL : str = "The loss as the first prediction moves, the others held"; +pub const SAY_GRAD_LABEL : str = "The gradient for each prediction"; +pub const SAY_LOSS : str = "loss"; +pub const SAY_SURE_RIGHT : str = "0.99 where right"; +pub const SAY_SURE_WRONG : str = "0.01 where right"; +pub const SAY_LOGITS : str = "logits 0, 0, 0"; +pub const SAY_NOTE : str = "The loss of one case is -(t log p + (1 - t) log(1 - p)). The gradient of a prediction is huge where the model is sure and wrong, and small where it is sure and right."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/binary_crossentropy_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_targets_are_the_spec_fixture { + assert K_TARGETS[0] == 1; + assert K_TARGETS[1] == 0; + assert K_TARGETS[2] == 1; +} + +test the_window_stays_inside_zero_and_one { + assert K_P_LO_C > 0; + assert K_P_HI_C < 100; + assert K_PRESET_B_C[1] == K_P_LO_C; + assert K_PRESET_A_C[1] == K_P_HI_C; +} diff --git a/apps/website/specs/widgets/nn-conv.t27 b/apps/website/specs/widgets/nn-conv.t27 new file mode 100644 index 0000000000..df845ff1df --- /dev/null +++ b/apps/website/specs/widgets/nn-conv.t27 @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-conv.t27 -- a window over a picture: 2 x 2 average pooling +; Source of truth for public/widgets/nn-conv/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-conv/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/avgpool2d_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 10 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader taps a window, on the image or on the output, and toggles the gradient +; view. Outputs are pool4_at(i), the output side calc_output_size(4) and the gradient +; backward4_at(i) for the spec's output gradients (4, 8, 12, 16). + +; WHAT IT DOES NOT CLAIM: this is AVERAGE pooling with a fixed 2 x 2 window, not a convolution with +; a learned kernel: the sliding conv2d spec is gHashTag/t27#10612, not merged when this page was +; made. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_conv; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-conv"; +pub const TITLE : str = "Patches of a picture: a 2 x 2 window, averaged"; +pub const DESCRIPTION : str = "Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch."; +pub const IMAGE_ALT : str = "Window card: a 4 x 4 image holding 0 to 15, with the 2 x 2 patch 2, 3, 6, 7 outlined and the rest dimmed; beside it the 2 x 2 output 2.50, 4.50, 10.50, 12.50 with 4.50 outlined. Tiles read window 2 / 4, average 4.50, output 2 x 2 and gradient share 2.00."; +pub const HOOK : str = "Pictures are read in patches. Here a 2 x 2 window steps by 2 over a 4 x 4 image and averages: 2.5, 4.5, 10.5, 12.5. A learned kernel comes next."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/avgpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 10 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SIDE : u8 = 4; +pub const K_KERNEL : u8 = 2; +pub const K_DEFAULT_KERNEL : u8 = 2; +pub const K_DEFAULT_STRIDE : u8 = 2; +pub const K_WIN_ROW : [4]u8 = [0, 0, 2, 2]; +pub const K_WIN_COL : [4]u8 = [0, 2, 0, 2]; +pub const K_PRESET_WIN : [3]u8 = [1, 0, 3]; +pub const K_PRESET_GRAD : [3]u8 = [0, 0, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["Window 2", "Window 1", "The gradient of window 4"]; +pub const SAY_ASK : str = "How does a network look at a picture: all at once, or in patches?"; +pub const SAY_SHOW_GRAD : str = "show the gradient"; +pub const SAY_IN_LABEL : str = "The 4 x 4 input: tap a patch"; +pub const SAY_GRAD_LABEL : str = "The gradient each input receives"; +pub const SAY_OUT_LABEL : str = "The 2 x 2 output: one number per patch"; +pub const SAY_WINDOW : str = "window"; +pub const SAY_AVERAGE : str = "its average"; +pub const SAY_OUT_SIDE : str = "output"; +pub const SAY_GRAD_SHARE : str = "gradient per input"; +pub const SAY_NOTE : str = "Average pooling, not yet a convolution: every window weighs its four cells equally. A convolution would weigh them with a learned 2 x 2 kernel and usually step by 1; that spec (t27#10612) is still open."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/avgpool2d_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_windows_tile_the_image { + assert K_SIDE == 4; + assert K_KERNEL == 2; + assert K_WIN_ROW[3] + K_KERNEL == K_SIDE; + assert K_WIN_COL[1] + K_KERNEL == K_SIDE; +} + +test the_window_steps_by_its_own_size { + assert K_DEFAULT_KERNEL == K_DEFAULT_STRIDE; + assert K_WIN_COL[1] == K_DEFAULT_STRIDE; + assert K_PRESET_WIN[2] == 3; +} diff --git a/apps/website/specs/widgets/nn-dropout.t27 b/apps/website/specs/widgets/nn-dropout.t27 new file mode 100644 index 0000000000..dcee5951e5 --- /dev/null +++ b/apps/website/specs/widgets/nn-dropout.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-dropout.t27 -- dropout, inverted and classic: training with neurons switched off +; Source of truth for public/widgets/nn-dropout/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-dropout/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/dropout_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 9 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles training and inverted scaling. The rows are forward_at(false, +; true, i) (the identity, so the input), forward_at(training, scaled, i) and, while training, +; backward_at(scaled, i). + +; WHAT IT DOES NOT CLAIM: the mask is the spec's fixed one (keep, drop, keep, drop) with p 0.5, not +; a random draw; the point is the scaling, not the sampling. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_dropout; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-dropout"; +pub const TITLE : str = "Dropout: training a network with neurons switched off"; +pub const DESCRIPTION : str = "Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size."; +pub const IMAGE_ALT : str = "Dropout card, training with inverted dropout: three rows of four cells. Input 1, 2, 3, 4; output 2, 0, 6, 0 with units 1 and 3 dimmed; gradient 2, 0, 2, 0. Tiles read mode training, a kept unit 2.00, a dropped unit 0.00 and the kept gradient 2.00."; +pub const HOOK : str = "With p = 0.5, inverted dropout doubles the units it keeps while training (1, 2, 3, 4 becomes 2, 0, 6, 0) and leaves inference alone."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/dropout_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 9 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_UNITS : u8 = 4; +pub const K_PRESET_TRAIN : [4]u8 = [1, 1, 0, 0]; +pub const K_PRESET_SCALED : [4]u8 = [1, 0, 1, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Training, inverted", "Training, classic", "Inference, inverted", "Inference, classic"]; +pub const SAY_ASK : str = "Why would a network train with some of its neurons switched off?"; +pub const SAY_TRAINING : str = "training"; +pub const SAY_SCALED : str = "inverted (scale while training)"; +pub const SAY_GRID_LABEL : str = "Input, output and gradient of four units through dropout"; +pub const SAY_IN : str = "input"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "gradient"; +pub const SAY_UNIT : str = "unit"; +pub const SAY_MODE : str = "mode"; +pub const SAY_MODE_TRAIN : str = "training"; +pub const SAY_MODE_INFER : str = "inference"; +pub const SAY_KEPT_UNIT : str = "unit 0, kept"; +pub const SAY_DROPPED_UNIT : str = "unit 1, dropped"; +pub const SAY_GRAD_KEPT : str = "gradient, kept unit"; +pub const SAY_NOTE : str = "Dropping random units forces the rest not to lean on any one of them. Inverted dropout scales by 1 / (1 - p) while training so that inference is a plain pass; classic dropout scales by 1 - p at inference instead."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/dropout_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test four_units_four_modes { + assert K_UNITS == 4; + assert K_PRESET_TRAIN[0] == 1; + assert K_PRESET_TRAIN[3] == 0; +} + +test every_mode_is_offered { + assert K_PRESET_SCALED[0] != K_PRESET_SCALED[1]; + assert K_PRESET_SCALED[2] != K_PRESET_SCALED[3]; + assert K_START_PRESET == 0; +} diff --git a/apps/website/specs/widgets/nn-elu.t27 b/apps/website/specs/widgets/nn-elu.t27 new file mode 100644 index 0000000000..9d38c009ac --- /dev/null +++ b/apps/website/specs/widgets/nn-elu.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-elu.t27 -- ELU: a negative side with a floor at -alpha +; Source of truth for public/widgets/nn-elu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-elu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/elu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 6 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -5 to 3 and sets alpha from 0.1 to 2. The curve is +; forward(x, alpha), the slope derivative(x, alpha), and the floor line is forward far to the left +; (x = -100). + +; WHAT IT DOES NOT CLAIM: the floor is read as forward(-100, alpha), which is -alpha to f32 +; precision, not the limit itself. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_elu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-elu"; +pub const TITLE : str = "ELU: a negative side with a floor"; +pub const DESCRIPTION : str = "Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies."; +pub const IMAGE_ALT : str = "ELU card at alpha 1, x = -3: the green curve runs along the diagonal for positive x and bends down toward the red dashed floor at -1 on the left; the dashed gold slope is 1 on the right and decays toward 0 on the left. Tiles read -0.9502, slope 0.0498, floor -1.0000 and the spec batch (-1, 0, 2) as -0.632 0.000 2.000."; +pub const HOOK : str = "ELU(-3) with alpha 1 is -0.9502, already 95% of the way to its floor of -1, and its slope there is still 0.0498, not 0."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/elu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 6 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -500; +pub const K_X_HI_C : i16 = 300; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -220; +pub const K_Y_HI_C : i16 = 300; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 3]; +pub const K_Y_TICKS : [6]i8 = [-2, -1, 0, 1, 2, 3]; +pub const K_ALPHA_LO_C : u8 = 10; +pub const K_ALPHA_HI_C : u8 = 200; +pub const K_ALPHA_STEP_C : u8 = 5; +pub const K_FAR_LEFT : u8 = 100; +pub const K_PRESET_X_C : [4]i16 = [-300, -300, 150, -100]; +pub const K_PRESET_ALPHA_C : [4]u8 = [100, 50, 100, 200]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["alpha 1, x = -3", "alpha 0.5, x = -3", "alpha 1, x = 1.5", "alpha 2, x = -1"]; +pub const SAY_ASK : str = "What if the negative side had a floor instead of a cliff?"; +pub const SAY_X : str = "input x"; +pub const SAY_ALPHA : str = "alpha"; +pub const SAY_F : str = "ELU(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_FLOOR : str = "floor"; +pub const SAY_PLOT_LABEL : str = "ELU of x, its slope and its floor from -5 to 3"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch -1 0 2"; +pub const SAY_NOTE : str = "ReLU throws the negative side away; ELU keeps a soft version of it, so a unit stuck below zero still moves. alpha is how deep the floor lies."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/elu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_floor_is_far_left { + assert K_FAR_LEFT == 100; + assert K_FAR_LEFT * 100 + K_X_LO_C > 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_ALPHA_C[3] == K_ALPHA_HI_C; + assert K_PRESET_ALPHA_C[1] >= K_ALPHA_LO_C; + assert K_Y_LO_C + 200 < 0; +} diff --git a/apps/website/specs/widgets/nn-embedding.t27 b/apps/website/specs/widgets/nn-embedding.t27 new file mode 100644 index 0000000000..309aaa6fd1 --- /dev/null +++ b/apps/website/specs/widgets/nn-embedding.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-embedding.t27 -- the embedding table: a word becomes a row of numbers +; Source of truth for public/widgets/nn-embedding/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-embedding/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/embedding_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 8 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks two tokens from four. The table is lookup_at(v, v, j) for every row +; v, the output lookup_at(a, b, i), and the gradient table grad_at(a, b, i) for the spec's gradient +; rows (1, 2) and (3, 4). + +; WHAT IT DOES NOT CLAIM: the table is the spec's 4 x 2 fixture (row v = 10 v, 10 v + 1); a real one +; has a row per word and hundreds of columns. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_embedding; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-embedding"; +pub const TITLE : str = "Embeddings: how a word becomes a row of numbers"; +pub const DESCRIPTION : str = "Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both."; +pub const IMAGE_ALT : str = "Embedding card: token 2 read twice from a 4 x 2 table whose rows are (0, 1), (10, 11), (20, 21), (30, 31). Row 2 is outlined and the others dimmed; the output is (20, 21) twice, and the gradient table is all zero except row 2, which holds 4 and 6."; +pub const HOOK : str = "A token is an index into a table, nothing more. Read token 2 twice and its row's gradient is (1 + 3, 2 + 4) = (4, 6); the other rows get 0."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/embedding_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 8 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_VOCAB : u8 = 4; +pub const K_WIDTH : u8 = 2; +pub const K_PRESET_A : [3]u8 = [2, 1, 0]; +pub const K_PRESET_B : [3]u8 = [2, 3, 2]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["The same token twice", "Tokens 1 and 3", "Tokens 0 and 2"]; +pub const SAY_ASK : str = "How does a word become numbers a network can use?"; +pub const SAY_TOKEN_NAMES : [4]str = ["token 0", "token 1", "token 2", "token 3"]; +pub const SAY_FIRST : str = "first token"; +pub const SAY_SECOND : str = "second token"; +pub const SAY_DIM : str = "dim"; +pub const SAY_TABLE_LABEL : str = "The embedding table: one row per token"; +pub const SAY_OUT_LABEL : str = "What the layer outputs"; +pub const SAY_GRAD_LABEL : str = "Where the gradient lands"; +pub const SAY_ROWS_TOUCHED : str = "rows read"; +pub const SAY_ONE_ROW : str = "one row, twice"; +pub const SAY_TWO_ROWS : str = "two rows"; +pub const SAY_VECTORS : str = "output"; +pub const SAY_GRAD_ROW : str = "gradient of {0}"; +pub const SAY_NOTE : str = "An embedding layer has no multiply at all: it copies rows. Learning changes only the rows it copied, which is why a rare word learns slowly."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/embedding_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_table_is_the_spec_fixture { + assert K_VOCAB == 4; + assert K_WIDTH == 2; + assert K_VOCAB * K_WIDTH == 8; +} + +test the_presets_name_real_tokens { + assert K_PRESET_A[0] == K_PRESET_B[0]; + assert K_PRESET_B[1] < K_VOCAB; + assert K_PRESET_A[1] != K_PRESET_B[1]; +} diff --git a/apps/website/specs/widgets/nn-encoder.t27 b/apps/website/specs/widgets/nn-encoder.t27 new file mode 100644 index 0000000000..66df55b1cc --- /dev/null +++ b/apps/website/specs/widgets/nn-encoder.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-encoder.t27 -- a transformer encoder block, post-norm and pre-norm +; Source of truth for public/widgets/nn-encoder/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-encoder/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/transformer/encoder_block.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 26 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader toggles post-norm and pre-norm. The output grid is block_at(pre, 0, i), +; the row means and variances block_at(pre, 1 or 2, row), and the attention grids attention_at(1, +; i): 3 positions, d_model 4, 2 heads, d_ff 8, the spec's weights. + +; WHAT IT DOES NOT CLAIM: one block with the spec's fixed weights, not a trained model; a +; transformer stacks dozens. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_encoder; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-encoder"; +pub const TITLE : str = "An encoder block: what one transformer layer does"; +pub const DESCRIPTION : str = "Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not."; +pub const IMAGE_ALT : str = "Encoder card, post-norm: a 3 x 4 output grid in pink and green, every row centred on 0. Tiles read row means 0.000 0.000 0.000 and variances 1.000 1.000 1.000. Below, two 3 x 3 attention grids of the block, head 0 row 0 reading 0.401 0.198 0.401."; +pub const HOOK : str = "Post-norm rows come out at mean 0 and variance 1.000; pre-norm rows at variances 2.73, 3.33 and 0.96, because its last step is a residual add."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/transformer/encoder_block.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 26 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SEQ : u8 = 3; +pub const K_D_MODEL : u8 = 4; +pub const K_HEADS : u8 = 2; +pub const K_PRESET_PRE : [2]u8 = [0, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [2]str = ["Post-norm", "Pre-norm"]; +pub const SAY_ASK : str = "What does one layer of a transformer actually do to its input?"; +pub const SAY_PRE_NORM : str = "pre-norm"; +pub const SAY_HEAD : str = "head"; +pub const SAY_POS : str = "pos"; +pub const SAY_DIM : str = "dim"; +pub const SAY_OUT_LABEL : str = "The block's output: 3 positions x 4 dimensions"; +pub const SAY_ATT_LABEL : str = "The block's self-attention weights"; +pub const SAY_MEANS : str = "row means"; +pub const SAY_VARS : str = "row variances"; +pub const SAY_ORDER : str = "order"; +pub const SAY_ORDER_POST : str = "attend, add, norm, FFN, add, norm"; +pub const SAY_ORDER_PRE : str = "norm, attend, add, norm, FFN, add"; +pub const SAY_ATT_ROW : str = "head 0, pos 0 reads"; +pub const SAY_NOTE : str = "The residual adds keep the input flowing through, so a deep stack can train; the norms keep the numbers in range. Where the norm sits decides what comes out."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/transformer/encoder_block.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test two_heads_split_the_model { + assert K_HEADS * 2 == K_D_MODEL; + assert K_SEQ == 3; +} + +test both_orders_are_offered { + assert K_PRESET_PRE[0] == 0; + assert K_PRESET_PRE[1] == 1; +} diff --git a/apps/website/specs/widgets/nn-gelu.t27 b/apps/website/specs/widgets/nn-gelu.t27 new file mode 100644 index 0000000000..7a202a415b --- /dev/null +++ b/apps/website/specs/widgets/nn-gelu.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-gelu.t27 -- GELU, exact and tanh form: the bend transformers use +; Source of truth for public/widgets/nn-gelu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-gelu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/gelu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 4 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 3. The exact curve is forward_at(x, false) through the +; spec's erf, the dashed curve forward_at(x, true), the tanh form, and the dotted curve backward_at, +; the slope. + +; WHAT IT DOES NOT CLAIM: the erf of the spec is the Abramowitz-Stegun 7.1.26 fit, good to 1.5e-7, +; so the exact curve is exact to that. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_gelu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-gelu"; +pub const TITLE : str = "GELU: why transformers bend a little below zero"; +pub const DESCRIPTION : str = "Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form."; +pub const IMAGE_ALT : str = "GELU card at x = -0.75: the thick green exact curve and the dashed pink tanh form lie on top of each other from -4 to 3, dipping just under zero near -0.75; the dotted cyan slope crosses zero there. Tiles read exact -0.16997, tanh form -0.17004 and slopes 0.0008."; +pub const HOOK : str = "GELU(-0.75) = -0.16997 exactly and -0.17004 by the tanh form. A smooth ReLU with a small dip, used in BERT and GPT."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/gelu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 4 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 300; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -50; +pub const K_Y_HI_C : i16 = 300; +pub const K_X_TICKS : [8]i8 = [-4, -3, -2, -1, 0, 1, 2, 3]; +pub const K_Y_TICKS_C : [4]i16 = [0, 100, 200, 300]; +pub const K_PRESET_X_C : [4]i16 = [-75, 150, -300, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["The dip, x = -0.75", "x = 1.5", "Far left, x = -3", "x = 0"]; +pub const SAY_ASK : str = "Why do transformers use a curve that bends a little below zero?"; +pub const SAY_X : str = "input x"; +pub const SAY_EXACT : str = "GELU, exact"; +pub const SAY_TANH : str = "GELU, tanh form"; +pub const SAY_DF : str = "slope"; +pub const SAY_DF_TANH : str = "slope, tanh form"; +pub const SAY_PLOT_LABEL : str = "GELU of x, exact and tanh form, and its slope from -4 to 3"; +pub const SAY_NOTE : str = "GELU(x) = x Phi(x): a positive input mostly passes, a large negative one mostly vanishes, and in between the curve dips. Unlike ReLU its slope is smooth everywhere."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/gelu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_dip_is_in_range { + assert K_PRESET_X_C[0] < 0; + assert K_PRESET_X_C[0] > K_X_LO_C; + assert K_Y_LO_C < 0; +} + +test the_window_is_wider_on_the_left { + assert K_X_LO_C + 400 == 0; + assert K_X_HI_C == 300; + assert K_X_TICKS[0] * 100 == K_X_LO_C; +} diff --git a/apps/website/specs/widgets/nn-huber.t27 b/apps/website/specs/widgets/nn-huber.t27 new file mode 100644 index 0000000000..2db4401c30 --- /dev/null +++ b/apps/website/specs/widgets/nn-huber.t27 @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-huber.t27 -- the Huber loss: square inside delta, linear outside +; Source of truth for public/widgets/nn-huber/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-huber/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/huber_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 15 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the error from -4 to 4 and sets delta from 0.25 to 3. The green +; curve is huber_one(e, delta), the dashed curve huber_one(e, 1000), which never leaves its +; quadratic part on this window, and the tiles huber_two on the spec's pair. + +; WHAT IT DOES NOT CLAIM: the 30-error figure in the hook is the same two fns at e = 30, read off +; the compiled logic, not a measurement of a model. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_huber; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-huber"; +pub const TITLE : str = "Huber loss: a loss that does not panic at an outlier"; +pub const DESCRIPTION : str = "Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square."; +pub const IMAGE_ALT : str = "Huber card at delta 1, error 3: the green Huber curve is a small parabola between the cyan dashed lines at -1 and 1 and then two straight arms; the dashed gold square climbs much faster. Tiles read Huber 2.5000, square 4.5000 and, for the spec's pair of errors (0.5, 3), 1.3125 against 2.3125."; +pub const HOOK : str = "An error of 3 costs 2.5 under Huber with delta 1 and 4.5 squared. At 30 the gap is 29.5 against 450: why robust regression uses it."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/huber_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 15 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_E_LO_C : i16 = -400; +pub const K_E_HI_C : u16 = 400; +pub const K_Y_HI_C : u16 = 800; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [5]u8 = [0, 2, 4, 6, 8]; +pub const K_DELTA_LO_C : u8 = 25; +pub const K_DELTA_HI_C : u16 = 300; +pub const K_WIDE : u16 = 1000; +pub const K_PAIR_C : [2]u16 = [50, 300]; +pub const K_PRESET_E_C : [4]i16 = [300, 50, -300, 200]; +pub const K_PRESET_DELTA_C : [4]u16 = [100, 100, 50, 300]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Error 3, delta 1", "Error 0.5, delta 1", "Error -3, delta 0.5", "Error 2, delta 3"]; +pub const SAY_ASK : str = "Can a loss stay calm when one data point is far off?"; +pub const SAY_E : str = "error e"; +pub const SAY_DELTA : str = "delta"; +pub const SAY_HUBER : str = "Huber"; +pub const SAY_SQUARE : str = "half the square"; +pub const SAY_PLOT_LABEL : str = "Huber loss and half the squared error as the error goes from -4 to 4"; +pub const SAY_PAIR : str = "Huber of ({0}, {1})"; +pub const SAY_PAIR_SQ : str = "square of ({0}, {1})"; +pub const SAY_NOTE : str = "Inside delta Huber is the square; outside it is delta |e| - delta^2 / 2, joined so that value and slope agree. Its gradient never grows past delta."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/huber_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_wide_delta_never_clips_the_window { + assert K_WIDE * 100 > K_E_HI_C; + assert K_DELTA_HI_C < K_WIDE * 100; +} + +test the_pair_is_the_spec_example { + assert K_PAIR_C[0] == 50; + assert K_PAIR_C[1] == 300; + assert K_PRESET_DELTA_C[3] == K_DELTA_HI_C; +} diff --git a/apps/website/specs/widgets/nn-lamb.t27 b/apps/website/specs/widgets/nn-lamb.t27 new file mode 100644 index 0000000000..4d550fb9e8 --- /dev/null +++ b/apps/website/specs/widgets/nn-lamb.t27 @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-lamb.t27 -- LAMB: a layer-wise trust ratio for large batches +; Source of truth for public/widgets/nn-lamb/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-lamb/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/lamb.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 21 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the scale of the weights (1, 2) from 0.1 to 10. Every point is +; step_norm(scale), the norm of the LAMB update for gradients (0.1, 0.2) at lr 0.001, and the tiles +; two_layers, one step on two layers at once. + +; WHAT IT DOES NOT CLAIM: the clip at a norm of 10 is the spec's DEFAULT_CLIP_THRESHOLD; the flat +; part is that cap, not a property of every LAMB. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_lamb; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-lamb"; +pub const TITLE : str = "LAMB: one learning rate for layers of every size"; +pub const DESCRIPTION : str = "Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing."; +pub const IMAGE_ALT : str = "LAMB card at scale 2: a green line rises straight from 0 at scale 0 and bends flat at 0.010 once the scale passes about 4.5, with the cursor at 0.00447. Tiles read step norm 0.004472, ten times the weights 0.010000, and the spec's two layers after one step 0.9984 1.9984 and 2.9965 3.9964."; +pub const HOOK : str = "Weights (2, 4) take a step of 0.00447 and weights (6, 12) one of 0.01: a step is 0.001 of the layer's norm, capped at 10. That is how LAMB trains large batches."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/lamb.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 21 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SCALE_LO_C : u8 = 10; +pub const K_SCALE_HI_C : u16 = 1000; +pub const K_Y_HI_U : u8 = 12; +pub const K_Y_TICKS_U : [5]u8 = [0, 3, 6, 9, 12]; +pub const K_X_TICKS : [6]u8 = [0, 2, 4, 6, 8, 10]; +pub const K_PRESET_SCALE_C : [4]u16 = [200, 600, 10, 1000]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["scale 2", "scale 6, capped", "scale 0.1", "scale 10"]; +pub const SAY_ASK : str = "Can one learning rate suit a tiny layer and a huge one?"; +pub const SAY_SCALE : str = "weight scale"; +pub const SAY_NORM : str = "step norm"; +pub const SAY_PLOT_LABEL : str = "The norm of one LAMB step as the layer's weights are scaled"; +pub const SAY_NORM_X10 : str = "weights x 10"; +pub const SAY_LAYER_A : str = "layer 1 after a step"; +pub const SAY_LAYER_B : str = "layer 2 after a step"; +pub const SAY_NOTE : str = "LAMB computes an Adam-style update for each layer, then rescales it by the trust ratio min(||w||, 10) / ||update||. A big layer takes a big step and a small layer a small one."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/lamb.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_window_reaches_the_cap { + assert K_SCALE_HI_C == 1000; + assert K_PRESET_SCALE_C[1] > 448; + assert K_PRESET_SCALE_C[0] < 448; +} + +test the_axis_holds_the_cap { + assert K_Y_HI_U > 10; + assert K_Y_TICKS_U[4] == K_Y_HI_U; + assert K_PRESET_SCALE_C[2] == K_SCALE_LO_C; +} diff --git a/apps/website/specs/widgets/nn-lstm.t27 b/apps/website/specs/widgets/nn-lstm.t27 new file mode 100644 index 0000000000..aeaa04a2ba --- /dev/null +++ b/apps/website/specs/widgets/nn-lstm.t27 @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-lstm.t27 -- an LSTM cell's gates: forget, input, output +; Source of truth for public/widgets/nn-lstm/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-lstm/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/lstm_single.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 23 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets four gate biases from -6 to 6 and the old memory from -2 to 2. With +; every weight 0, each gate is sigmoid(bias); the new memory and output are bias_only(b_i, b_f, b_g, +; b_o, c_prev, which) of the spec. + +; WHAT IT DOES NOT CLAIM: one step of a 1-unit cell with all weights 0, so the gates see only their +; biases; that is the spec's own fixture. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_lstm; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-lstm"; +pub const TITLE : str = "LSTM gates: how a cell decides what to keep"; +pub const DESCRIPTION : str = "Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate."; +pub const IMAGE_ALT : str = "LSTM card, remember: gate bars forget 0.998, input 0.002 and output 0.998; memory bars old 1.000, new 0.998 and output 0.759. Tiles read new memory 0.9975, output 0.7587, forget 0.9975 and input 0.0025."; +pub const HOOK : str = "With the forget gate open (0.9975) and the input gate shut, a memory of 1 comes out as 0.9975: an LSTM can hold a value for a long time."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/lstm_single.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 23 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_BIAS_HI_C : u16 = 600; +pub const K_C_LO_C : i16 = -200; +pub const K_C_HI_C : u16 = 200; +pub const K_CELL_LO : i8 = -3; +pub const K_CELL_HI : u8 = 3; +pub const K_GATE_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_CELL_TICKS : [5]i8 = [-2, -1, 0, 1, 2]; +pub const K_PRESET_BF_C : [4]i16 = [600, -600, -600, 600]; +pub const K_PRESET_BI_C : [4]i16 = [-600, 0, 600, -600]; +pub const K_PRESET_BG_C : [4]i16 = [0, 0, 600, 0]; +pub const K_PRESET_BO_C : [4]i16 = [600, 600, 600, -600]; +pub const K_PRESET_C_C : [4]i16 = [100, 100, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Remember", "Forget", "Write", "Hide"]; +pub const SAY_ASK : str = "How does a memory cell decide what to keep and what to forget?"; +pub const SAY_BF : str = "forget bias"; +pub const SAY_BI : str = "input bias"; +pub const SAY_BG : str = "candidate bias"; +pub const SAY_BO : str = "output bias"; +pub const SAY_C_PREV : str = "old memory c"; +pub const SAY_GATES_LABEL : str = "The three gates, each a sigmoid of its bias"; +pub const SAY_CELL_LABEL : str = "The memory before and after, and the output"; +pub const SAY_FORGET : str = "forget"; +pub const SAY_INPUT : str = "input"; +pub const SAY_OUTPUT : str = "output"; +pub const SAY_C_OLD : str = "old c"; +pub const SAY_C_NEW : str = "new c"; +pub const SAY_H_NEW : str = "output h"; +pub const SAY_NOTE : str = "c' = f c + i g and h' = o tanh(c'). When f is near 1 and i near 0, c passes through almost untouched, and so does its gradient: the long memory the plain cell lacked."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/lstm_single.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_biases_are_symmetric { + assert K_BIAS_HI_C == 600; + assert K_PRESET_BF_C[1] + K_BIAS_HI_C == 0; + assert K_PRESET_BG_C[2] == K_BIAS_HI_C; +} + +test the_presets_cover_the_gates { + assert K_PRESET_BF_C[0] > 0; + assert K_PRESET_BI_C[0] < 0; + assert K_PRESET_BO_C[3] < 0; + assert K_PRESET_C_C[0] <= K_C_HI_C; +} diff --git a/apps/website/specs/widgets/nn-maxpool.t27 b/apps/website/specs/widgets/nn-maxpool.t27 new file mode 100644 index 0000000000..f26b20b6c6 --- /dev/null +++ b/apps/website/specs/widgets/nn-maxpool.t27 @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-maxpool.t27 -- max pooling: keep the largest value of each window, and where it was +; Source of truth for public/widgets/nn-maxpool/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-maxpool/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 11 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks one of four window and stride pairs and taps an output. Outputs and +; argmax indices are pool_at(kernel, stride, 0 or 1, i); for 2 x 2 stride 2 the gradient view is +; backward_at(i), the spec's output gradients 1, 2, 3, 4. + +; WHAT IT DOES NOT CLAIM: the grid is the spec's fixture, repeated as K_INPUT; the outputs and +; argmax come from the compiled fn, so a K_INPUT that drifted would show a max that is not in its +; window. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_maxpool; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-maxpool"; +pub const TITLE : str = "Max pooling: what a network keeps when it shrinks a picture"; +pub const DESCRIPTION : str = "Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell."; +pub const IMAGE_ALT : str = "Max-pool card, 2 x 2 windows with stride 2: the spec's 4 x 4 grid in pink and green, with cell 13 (value 9) outlined inside its window; the 2 x 2 output reads 4, 8, 9, -2 with 9 outlined. Tiles read max 9, argmax 13, output 2 x 2 and gradient at the max 3."; +pub const HOOK : str = "On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2; their gradients land on cells 5, 6, 13 and 11 and nowhere else."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SIDE : u8 = 4; +pub const K_INPUT : [16]i8 = [1, 2, 5, 6, 3, 4, 8, 7, 0, -1, -3, -2, -4, 9, -6, -5]; +pub const K_KERNELS : [4]u8 = [2, 3, 2, 4]; +pub const K_STRIDES : [4]u8 = [2, 1, 1, 1]; +pub const K_OUT_SIDES : [4]u8 = [2, 2, 3, 1]; +pub const K_PRESET_CFG : [3]u8 = [0, 1, 2]; +pub const K_PRESET_CELL : [3]u8 = [2, 0, 4]; +pub const K_PRESET_GRAD : [3]u8 = [0, 0, 0]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [3]str = ["2 x 2, stride 2", "3 x 3, stride 1", "2 x 2, stride 1"]; +pub const SAY_ASK : str = "What does a network keep when it shrinks a picture?"; +pub const SAY_CONFIG : str = "window, stride"; +pub const SAY_CONFIG_NAMES : [4]str = ["2 x 2 / 2", "3 x 3 / 1", "2 x 2 / 1", "4 x 4 / 1"]; +pub const SAY_SHOW_GRAD : str = "show the gradient (2 x 2 / 2)"; +pub const SAY_IN_LABEL : str = "The spec's 4 x 4 input, the max of the window outlined"; +pub const SAY_GRAD_LABEL : str = "The gradient each input receives"; +pub const SAY_OUT_LABEL : str = "The output: tap a cell"; +pub const SAY_MAX : str = "max"; +pub const SAY_ARGMAX : str = "from cell"; +pub const SAY_OUT_SIDE : str = "output"; +pub const SAY_GRAD_AT_MAX : str = "gradient there"; +pub const SAY_NO_GRAD : str = "2 x 2 / 2 only"; +pub const SAY_NOTE : str = "A max pool forgets every value but one per window, which makes the network care less about exactly where a feature sits. In backpropagation the whole gradient of a window goes to its maximum."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/layers/maxpool2d_layer.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test every_output_side_follows_from_kernel_and_stride { + assert K_OUT_SIDES[0] * K_STRIDES[0] + K_KERNELS[0] - K_STRIDES[0] == K_SIDE; + assert K_OUT_SIDES[1] * K_STRIDES[1] + K_KERNELS[1] - K_STRIDES[1] == K_SIDE; + assert K_OUT_SIDES[2] * K_STRIDES[2] + K_KERNELS[2] - K_STRIDES[2] == K_SIDE; + assert K_OUT_SIDES[3] * K_STRIDES[3] + K_KERNELS[3] - K_STRIDES[3] == K_SIDE; +} + +test the_grid_is_the_spec_fixture { + assert K_INPUT[5] == 4; + assert K_INPUT[6] == 8; + assert K_INPUT[13] == 9; + assert K_INPUT[11] + 2 == 0; + assert K_OUT_SIDES[2] * K_OUT_SIDES[2] <= 9; +} diff --git a/apps/website/specs/widgets/nn-mse.t27 b/apps/website/specs/widgets/nn-mse.t27 new file mode 100644 index 0000000000..1f045e1fbd --- /dev/null +++ b/apps/website/specs/widgets/nn-mse.t27 @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-mse.t27 -- mean squared error: how wrong a guess is, as one number +; Source of truth for public/widgets/nn-mse/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-mse/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/loss/mse_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 13 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader moves three predictions from -1 to 5. The loss is mse_at(p0, p1, p2) +; against the spec's targets (1, 2, 3), each gradient mse_grad_at, and the bowl mse_at over p0. + +; WHAT IT DOES NOT CLAIM: the targets are the spec's fixture, repeated as K_TARGETS; every loss and +; gradient comes from the compiled fn. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_mse; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-mse"; +pub const TITLE : str = "Mean squared error: how wrong a guess is, as one number"; +pub const DESCRIPTION : str = "Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target."; +pub const IMAGE_ALT : str = "MSE card: predictions 1.5, 2 and 2 against targets 1, 2, 3 drawn as white rings with green dots, red dashed misses and pink gradient arrows. Below, the loss as prediction 0 moves is a gold parabola with its cursor at 1.5. Tiles read loss 0.4167, gradients 0.333 0.000 -0.667, loss at the targets 0.0000 and misses of 1 and 2 costing 0.333 and 1.333."; +pub const HOOK : str = "A miss of 1 costs 1 / 3 of the mean; a miss of 2 costs 4 / 3. Squaring is what makes MSE fear large errors and shrug at small ones."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/loss/mse_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 13 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_TARGETS : [3]u8 = [1, 2, 3]; +pub const K_P_LO_C : i16 = -100; +pub const K_P_HI_C : u16 = 500; +pub const K_P_TICKS : [7]i8 = [-1, 0, 1, 2, 3, 4, 5]; +pub const K_LOSS_HI_C : u16 = 600; +pub const K_LOSS_TICKS : [4]u8 = [0, 2, 4, 6]; +pub const K_PRESET_P0_C : [4]i16 = [150, 100, 300, -100]; +pub const K_PRESET_P1_C : [4]u16 = [200, 200, 200, 400]; +pub const K_PRESET_P2_C : [4]u16 = [200, 300, 300, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["1.5, 2, 2", "On target", "One miss of 2", "All wrong"]; +pub const SAY_ASK : str = "How wrong is a guess, as one number?"; +pub const SAY_PRED : str = "prediction"; +pub const SAY_TARGET : str = "target"; +pub const SAY_GRAD : str = "minus the gradient"; +pub const SAY_MISS_LABEL : str = "Each prediction, its target and the step the gradient asks for"; +pub const SAY_BOWL_LABEL : str = "The loss as prediction 0 moves, the others held"; +pub const SAY_BOWL : str = "Drag along the bowl: the loss as prediction 0 alone moves."; +pub const SAY_LOSS : str = "loss"; +pub const SAY_GRADS : str = "gradients"; +pub const SAY_AT_TARGET : str = "loss on target"; +pub const SAY_DOUBLE : str = "miss of 1 / of 2"; +pub const SAY_NOTE : str = "The gradient of each prediction is 2 (p - t) / n: the further off, the harder the pull. Gradient descent follows it downhill into the bottom of the bowl."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/loss/mse_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_targets_are_the_spec_fixture { + assert K_TARGETS[0] == 1; + assert K_TARGETS[1] == 2; + assert K_TARGETS[2] == 3; +} + +test the_presets_stay_in_range { + assert K_PRESET_P0_C[3] >= K_P_LO_C; + assert K_PRESET_P1_C[3] <= K_P_HI_C; + assert K_PRESET_P0_C[1] == K_TARGETS[0] * 100; +} diff --git a/apps/website/specs/widgets/nn-positions.t27 b/apps/website/specs/widgets/nn-positions.t27 new file mode 100644 index 0000000000..1d38dcee64 --- /dev/null +++ b/apps/website/specs/widgets/nn-positions.t27 @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-positions.t27 -- sinusoidal positional encoding: stripes and clocks +; Source of truth for public/widgets/nn-positions/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-positions/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/transformer/positional_encoding.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 25 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the position from 0 to 200. Every stripe, hand and value is pe(pos, +; dim) of the spec at d_model 8; the speeds are inv_freq(pair, 8). + +; WHAT IT DOES NOT CLAIM: d_model 8 shows the pattern; a real model uses hundreds of dimensions, and +; many now learn or rotate positions instead. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_positions; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-positions"; +pub const TITLE : str = "Positional encoding: how a transformer knows word order"; +pub const DESCRIPTION : str = "Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows."; +pub const IMAGE_ALT : str = "Positional-encoding card at position 5: four clocks with coloured hands, the fastest turned far round, the slowest still pointing up. Below, a stripe chart of 48 positions by 8 dimensions in pink and green: the left columns flicker fast, the right ones barely change. Tiles read the 8 values and the 4 speeds 1, 0.1, 0.01, 0.001."; +pub const HOOK : str = "Position 5 is (-0.959, 0.284, 0.479, 0.878, 0.050, 0.999, 0.005, 1.000). Four clocks at speeds 1, 0.1, 0.01 and 0.001 give each position its own reading."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/transformer/positional_encoding.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 25 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_D_MODEL : u8 = 8; +pub const K_ROWS : u8 = 48; +pub const K_POS_HI : u8 = 200; +pub const K_PRESET_POS : [4]u8 = [5, 0, 1, 37]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Position 5", "Position 0", "Position 1", "Position 37"]; +pub const SAY_ASK : str = "Attention sees a set of words. How does it know their order?"; +pub const SAY_POS : str = "position"; +pub const SAY_STRIPES_LABEL : str = "pe(pos, dim) for positions 0 to 47 (rows) and the 8 dimensions"; +pub const SAY_CLOCKS_LABEL : str = "Each sin and cos pair as a clock hand, and its speed"; +pub const SAY_PAIR : str = "pair"; +pub const SAY_VECTOR : str = "the 8 numbers"; +pub const SAY_FAST : str = "fastest pair"; +pub const SAY_SLOW : str = "slowest pair"; +pub const SAY_FREQS : str = "speeds"; +pub const SAY_NOTE : str = "A shift by k positions turns every clock by its own fixed angle, so the distance between two positions is visible to a dot product. Position 0 is (0, 1, 0, 1, ...)."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/transformer/positional_encoding.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test eight_dimensions_four_clocks { + assert K_D_MODEL == 8; + assert K_D_MODEL % 2 == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_POS[3] < K_ROWS; + assert K_PRESET_POS[1] == 0; + assert K_POS_HI > K_ROWS; +} diff --git a/apps/website/specs/widgets/nn-ppo.t27 b/apps/website/specs/widgets/nn-ppo.t27 new file mode 100644 index 0000000000..f32a2aeb05 --- /dev/null +++ b/apps/website/specs/widgets/nn-ppo.t27 @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-ppo.t27 -- PPO's clipped surrogate: a reward that stops pulling +; Source of truth for public/widgets/nn-ppo/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-ppo/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/rl/ppo_clip_loss.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 27 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags r from 0 to 2 and sets the advantage A from -2 to 2 and eps from +; 0.05 to 0.5. The green curve is clipped_surrogate(r, A, eps), the dashed one clipped_surrogate(r, +; A, 1000), which never clips here, and the tiles policy_loss_of on the spec's advantages (2, 1.5, +; 3). + +; WHAT IT DOES NOT CLAIM: the objective of one sample; PPO averages it over a batch, adds value and +; entropy terms (total_loss in the spec) and runs it for a few epochs per batch. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_ppo; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-ppo"; +pub const TITLE : str = "PPO: how an agent learns from reward without lurching"; +pub const DESCRIPTION : str = "Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling."; +pub const IMAGE_ALT : str = "PPO card at r = 1.5, A = 1, eps 0.2: the dashed gold raw objective is a straight line through the origin; the thick green clipped one follows it and turns flat at 1.2 from r = 1.2 on. Tiles read clipped 1.2000, raw 1.5000, the spec batch policy loss -2.1167 and the same batch at r = 1.5, -2.6000."; +pub const HOOK : str = "At r = 1.5 with advantage 1 and eps 0.2, the raw objective is 1.5 but PPO counts only 1.2. The clip is what keeps one update from breaking the policy."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/rl/ppo_clip_loss.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 27 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_R_HI_C : u16 = 200; +pub const K_A_LO_C : i16 = -200; +pub const K_A_HI_C : u16 = 200; +pub const K_EPS_LO_C : u8 = 5; +pub const K_EPS_HI_C : u8 = 50; +pub const K_WIDE : u16 = 1000; +pub const K_Y_LO : i8 = -4; +pub const K_Y_HI : u8 = 4; +pub const K_Y_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_R_TICKS_C : [5]u8 = [0, 50, 100, 150, 200]; +pub const K_BATCH_R_C : [3]u8 = [100, 110, 90]; +pub const K_PRESET_R_C : [4]u8 = [150, 50, 150, 80]; +pub const K_PRESET_A_C : [4]i16 = [100, -100, 200, -200]; +pub const K_PRESET_EPS_C : [4]u8 = [20, 20, 50, 10]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["r 1.5, A 1", "r 0.5, A -1", "r 1.5, A 2, eps 0.5", "r 0.8, A -2, eps 0.1"]; +pub const SAY_ASK : str = "How does an agent learn from reward without lurching?"; +pub const SAY_R : str = "ratio r = new / old"; +pub const SAY_A : str = "advantage A"; +pub const SAY_EPS : str = "clip eps"; +pub const SAY_PLOT_LABEL : str = "PPO's clipped objective and the raw r A as the ratio goes from 0 to 2"; +pub const SAY_CLIPPED : str = "PPO objective"; +pub const SAY_RAW : str = "raw r A"; +pub const SAY_BATCH : str = "spec batch loss"; +pub const SAY_BATCH_FAR : str = "same batch at r"; +pub const SAY_NOTE : str = "A positive advantage says the action was better than expected, so raise its probability; past 1 + eps there is no more credit for it. A negative one is clipped at 1 - eps the same way."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/rl/ppo_clip_loss.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_wide_clip_never_clips_the_window { + assert K_WIDE * 100 > K_R_HI_C; + assert K_EPS_HI_C < 100; +} + +test the_presets_stay_in_range { + assert K_PRESET_R_C[0] <= K_R_HI_C; + assert K_PRESET_A_C[3] == K_A_LO_C; + assert K_PRESET_EPS_C[3] >= K_EPS_LO_C; + assert K_BATCH_R_C[0] == 100; +} diff --git a/apps/website/specs/widgets/nn-relu.t27 b/apps/website/specs/widgets/nn-relu.t27 new file mode 100644 index 0000000000..b63bcb47e7 --- /dev/null +++ b/apps/website/specs/widgets/nn-relu.t27 @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-relu.t27 -- ReLU and leaky ReLU: what a neuron does with a negative number +; Source of truth for public/widgets/nn-relu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-relu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/relu_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 1 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 4 and sets a leaky slope from 0 to 0.3. The green +; curve is forward_at over x and the dashed curve backward_at, the slope; the tiles read both at x +; and over the spec's own three-input batch (-2, 0, 2). + +; WHAT IT DOES NOT CLAIM: ReLU is one choice among the activations of module 2; the page measures +; nothing about training. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_relu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-relu"; +pub const TITLE : str = "ReLU: what a neuron does with a negative number"; +pub const DESCRIPTION : str = "Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through."; +pub const IMAGE_ALT : str = "ReLU card: leaky slope 0.1 at x = -2. The green curve is flat at -0.2 on the left and rises at 45 degrees on the right; the dashed gold slope sits at 0.1 then jumps to 1. Tiles read out -0.200, slope 0.100 and the spec's batch (-2, 0, 2) as -0.20 0.00 2.00."; +pub const HOOK : str = "max(0, x) is the whole rule, and its slope is 1 or 0. A leaky slope of 0.1 keeps a gradient alive on the negative side."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/relu_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 1 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 400; +pub const K_X_STEP_C : u8 = 5; +pub const K_Y_LO_C : i16 = -100; +pub const K_Y_HI_C : i16 = 400; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [6]i8 = [-1, 0, 1, 2, 3, 4]; +pub const K_SLOPE_MAX_C : u8 = 30; +pub const K_FIXTURE_C : [3]i16 = [-200, 0, 200]; +pub const K_PRESET_X_C : [4]i16 = [-200, 150, -200, -300]; +pub const K_PRESET_SLOPE_C : [4]u8 = [10, 0, 0, 30]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Leaky 0.1 at x = -2", "ReLU at x = 1.5", "ReLU at x = -2", "Leaky 0.3 at x = -3"]; +pub const SAY_ASK : str = "What does a neuron do with a negative number?"; +pub const SAY_X : str = "input x"; +pub const SAY_SLOPE : str = "leaky slope"; +pub const SAY_F : str = "ReLU(x)"; +pub const SAY_DF : str = "slope dReLU/dx"; +pub const SAY_PLOT_LABEL : str = "ReLU of x and its slope from -4 to 4, with a cursor you drag"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch -2 0 2"; +pub const SAY_BATCH_GRAD : str = "its slopes"; +pub const SAY_NOTE : str = "A slope of 0 means no gradient flows back, so a unit that only ever sees negative inputs stops learning. The leaky slope is the fix the spec takes as its fourth argument."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/relu_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_range_holds_both_sides { + assert K_X_LO_C < 0; + assert K_X_HI_C > 0; + assert K_X_LO_C + K_X_HI_C == 0; +} + +test the_presets_stay_in_range { + assert K_PRESET_X_C[3] >= K_X_LO_C; + assert K_PRESET_SLOPE_C[3] <= K_SLOPE_MAX_C; + assert K_PRESET_SLOPE_C[1] == 0; + assert K_FIXTURE_C[0] == K_PRESET_X_C[0]; +} diff --git a/apps/website/specs/widgets/nn-rmsprop.t27 b/apps/website/specs/widgets/nn-rmsprop.t27 new file mode 100644 index 0000000000..1ee610febf --- /dev/null +++ b/apps/website/specs/widgets/nn-rmsprop.t27 @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-rmsprop.t27 -- RMSProp: a step that ignores the size of the gradient +; Source of truth for public/widgets/nn-rmsprop/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-rmsprop/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/rmsprop.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 17 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader picks a gradient, a decay from 0.5 to 0.99 and a number of steps. Every +; point is param_after(g, n, decay) from 1.0 with lr 0.01, the cache cache_after(g, n) at the spec's +; decay 0.9. + +; WHAT IT DOES NOT CLAIM: a constant gradient on one weight; with a changing gradient the cache lags +; behind it. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_rmsprop; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-rmsprop"; +pub const TITLE : str = "RMSProp: a step that does not care how big the gradient is"; +pub const DESCRIPTION : str = "Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends."; +pub const IMAGE_ALT : str = "RMSProp card: gradient 0.5, decay 0.9, 100 steps. Three lines, green for 0.5 and dashed gold and pink for 0.001 and 1000, lie exactly on top of each other, falling from 1 to about -0.09. Tiles read the weight -0.09142, the three runs -0.0914 -0.0914 -0.0914, one step 0.96838 and the cache 0.249993."; +pub const HOOK : str = "Its first step is 0.0316 whether the gradient is 0.001 or 1000. Dividing by the gradient's own size is what makes the step scale-free."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/rmsprop.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 17 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 100; +pub const K_GRADS_M : [3]u32 = [1, 500, 1000000]; +pub const K_DECAY_LO_C : u8 = 50; +pub const K_DECAY_HI_C : u8 = 99; +pub const K_Y_LO_C : i16 = -110; +pub const K_Y_HI_C : u8 = 110; +pub const K_Y_TICKS_C : [5]i8 = [-100, -50, 0, 50, 100]; +pub const K_STEP_TICKS : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_G : [4]u8 = [1, 0, 2, 1]; +pub const K_PRESET_DECAY_C : [4]u8 = [90, 90, 90, 99]; +pub const K_PRESET_STEPS : [4]u8 = [100, 100, 100, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["g = 0.5", "g = 0.001", "g = 1000", "g = 0.5, decay 0.99"]; +pub const SAY_ASK : str = "Can a step ignore how big the gradient is?"; +pub const SAY_GRAD : str = "gradient"; +pub const SAY_GRAD_NAMES : [3]str = ["g = 0.001", "g = 0.5", "g = 1000"]; +pub const SAY_DECAY : str = "decay"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_PLOT_LABEL : str = "The weight after every step for three gradient sizes"; +pub const SAY_W_NOW : str = "weight now"; +pub const SAY_W_OTHERS : str = "all three gradients"; +pub const SAY_ONE_STEP : str = "after step 1"; +pub const SAY_CACHE : str = "cache, decay 0.9"; +pub const SAY_NOTE : str = "The cache is a running mean of g squared, so g / sqrt(cache) has no units: a layer whose gradients are tiny moves as fast as one whose gradients are huge."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/rmsprop.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_gradients_span_six_decades { + assert K_GRADS_M[0] == 1; + assert K_GRADS_M[2] == 1000000; + assert K_GRADS_M[1] == 500; +} + +test the_presets_stay_in_range { + assert K_PRESET_G[2] < 3; + assert K_PRESET_DECAY_C[3] == K_DECAY_HI_C; + assert K_PRESET_STEPS[0] == K_STEPS_HI; +} diff --git a/apps/website/specs/widgets/nn-rnn.t27 b/apps/website/specs/widgets/nn-rnn.t27 new file mode 100644 index 0000000000..2335230222 --- /dev/null +++ b/apps/website/specs/widgets/nn-rnn.t27 @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-rnn.t27 -- a recurrent cell: an echo that fades +; Source of truth for public/widgets/nn-rnn/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-rnn/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/recurrent/rnn_cell.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 22 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader taps each of eight inputs to cycle it through -1, 0 and +1. Each h is +; tiny_step(x, h) of the spec, applied in order from h = 0; the spec's own three-step run is +; tiny_sequence(t). + +; WHAT IT DOES NOT CLAIM: a 1-in, 1-hidden cell with the spec's weights (W_x 1, W_h 0.5, b 0); a +; real cell has a vector of hidden units. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_rnn; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-rnn"; +pub const TITLE : str = "Recurrent cells: how a network remembers a moment ago"; +pub const DESCRIPTION : str = "Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up."; +pub const IMAGE_ALT : str = "RNN card: inputs +1, 0, 0, +1, 0, 0, 0, 0 as cyan bars, and the green hidden state jumping to 0.76, fading to 0.36 and 0.18, jumping to 0.80 at the second pulse and fading to 0.05. Tiles read the last h 0.0466 and the spec's own run 0.7616 0.3634 0.1797."; +pub const HOOK : str = "A single pulse gives 0.762, 0.363, 0.180: the memory halves each step. A cell remembers, but not for long, which is the problem LSTMs solve."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/recurrent/rnn_cell.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 22 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS : u8 = 8; +pub const K_Y_TICKS : [3]i8 = [-1, 0, 1]; +pub const K_PRESET_INPUTS : [32]i8 = [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Two pulses", "One pulse", "Alternating", "Always on"]; +pub const SAY_ASK : str = "How does a network remember what it saw a moment ago?"; +pub const SAY_TAP : str = "Inputs: tap a step to change it"; +pub const SAY_STEP : str = "step"; +pub const SAY_X : str = "input x"; +pub const SAY_H : str = "hidden state h"; +pub const SAY_PLOT_LABEL : str = "Input and hidden state at every step"; +pub const SAY_H_LAST : str = "h, last step"; +pub const SAY_H_ALL : str = "h at every step"; +pub const SAY_SPEC_RUN : str = "spec run 1, 0, 0"; +pub const SAY_ECHO : str = "echo of one pulse"; +pub const SAY_NOTE : str = "The same weights act at every step, and the state h carries what came before. Because 0.5 h is squeezed by tanh each time, an old input fades geometrically."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/recurrent/rnn_cell.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test eight_steps_four_presets { + assert K_STEPS == 8; + assert K_PRESET_INPUTS[0] == 1; + assert K_PRESET_INPUTS[3] == 1; +} + +test the_inputs_are_trits { + assert K_PRESET_INPUTS[17] + 1 == 0; + assert K_PRESET_INPUTS[31] == 1; + assert K_PRESET_INPUTS[8] == 1; + assert K_PRESET_INPUTS[9] == 0; +} diff --git a/apps/website/specs/widgets/nn-sgd.t27 b/apps/website/specs/widgets/nn-sgd.t27 new file mode 100644 index 0000000000..6efd6e901e --- /dev/null +++ b/apps/website/specs/widgets/nn-sgd.t27 @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-sgd.t27 -- gradient descent with momentum and Nesterov +; Source of truth for public/widgets/nn-sgd/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-sgd/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/optimizer/sgd.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 16 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets lr from 0.01 to 1, momentum from 0 to 0.95, Nesterov and the number +; of steps. Every point is descend(lr, momentum, nesterov, n), the spec minimising (x - 3)^2 from 0; +; the dashed path is descend with momentum 0. + +; WHAT IT DOES NOT CLAIM: one weight on one bowl; a network has millions and its bowl is not a +; parabola. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_sgd; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-sgd"; +pub const TITLE : str = "Gradient descent: how a network walks downhill"; +pub const DESCRIPTION : str = "Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever."; +pub const IMAGE_ALT : str = "SGD card: momentum 0.9 at lr 0.1 for 50 steps. The green path of dots shoots up from 0 past the white dashed minimum at 3 to about 5.1, swings back below it and rings in toward 3; the dashed violet plain path creeps up smoothly. Tiles read x after 50 steps 3.09149, plain 2.99996 and step 1 at 0.6000."; +pub const HOOK : str = "lr 0.1 reaches 2.99996 in 50 steps. Add momentum 0.9 and it shoots to 5.13 first; at lr 1 it bounces between 0 and 6 for good."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/optimizer/sgd.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 16 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_STEPS_HI : u8 = 100; +pub const K_MINIMUM : u8 = 3; +pub const K_LR_LO_C : u8 = 1; +pub const K_LR_HI_C : u8 = 100; +pub const K_MOM_HI_C : u8 = 95; +pub const K_Y_LO : i8 = -1; +pub const K_Y_HI : u8 = 7; +pub const K_Y_TICKS : [5]i8 = [0, 2, 3, 4, 6]; +pub const K_STEP_TICKS : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_LR_C : [4]u8 = [10, 10, 10, 100]; +pub const K_PRESET_MOM_C : [4]u8 = [90, 0, 90, 0]; +pub const K_PRESET_NEST : [4]u8 = [0, 0, 1, 0]; +pub const K_PRESET_STEPS : [4]u8 = [50, 50, 50, 20]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Momentum 0.9", "Plain, lr 0.1", "Nesterov 0.9", "lr 1: it bounces"]; +pub const SAY_ASK : str = "How does a network walk downhill, and why does it overshoot?"; +pub const SAY_LR : str = "learning rate"; +pub const SAY_MOMENTUM : str = "momentum"; +pub const SAY_NESTEROV : str = "Nesterov"; +pub const SAY_STEPS : str = "steps"; +pub const SAY_PLOT_LABEL : str = "The weight after every step, from 0 toward the minimum at 3"; +pub const SAY_PATH : str = "this run"; +pub const SAY_PLAIN : str = "no momentum"; +pub const SAY_MIN : str = "the minimum"; +pub const SAY_X_NOW : str = "x after the steps"; +pub const SAY_X_PLAIN : str = "without momentum"; +pub const SAY_X_ONE : str = "after step 1"; +pub const SAY_NOTE : str = "Each step moves x by -lr times the gradient 2 (x - 3). Momentum adds 0.9 of the last move, which speeds up a long slope and overshoots a sharp bottom; Nesterov takes the gradient one step ahead."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/optimizer/sgd.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_minimum_is_inside_the_axis { + assert K_MINIMUM == 3; + assert K_Y_LO < 0; + assert K_Y_HI > K_MINIMUM * 2; +} + +test the_presets_stay_in_range { + assert K_PRESET_LR_C[3] == K_LR_HI_C; + assert K_PRESET_MOM_C[0] <= K_MOM_HI_C; + assert K_PRESET_STEPS[0] <= K_STEPS_HI; +} diff --git a/apps/website/specs/widgets/nn-sigmoid.t27 b/apps/website/specs/widgets/nn-sigmoid.t27 new file mode 100644 index 0000000000..f88b67dbf7 --- /dev/null +++ b/apps/website/specs/widgets/nn-sigmoid.t27 @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-sigmoid.t27 -- the sigmoid: any number into a probability +; Source of truth for public/widgets/nn-sigmoid/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-sigmoid/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/sigmoid_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 2 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -8 to 8. The curve is forward and the slope derivative of +; the spec, which takes the OUTPUT of the sigmoid, as backpropagation does; the tiles read the slope +; at x, at 0 and at the far right. + +; WHAT IT DOES NOT CLAIM: the slope bound of 0.25 is read off the compiled curve at x = 0, not +; proved here. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_sigmoid; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-sigmoid"; +pub const TITLE : str = "Sigmoid: turn any number into a probability"; +pub const DESCRIPTION : str = "Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends."; +pub const IMAGE_ALT : str = "Sigmoid card at x = 2: the green S-curve from 0 to 1 over -8..8, the dashed gold slope a bump peaking at 0.25 at x = 0. Tiles read sigmoid 0.8808, slope 0.1050, slope at 0 = 0.2500 and slope at 8 = 0.000335; two bars repeat the output and the slope."; +pub const HOOK : str = "1 / (1 + e^-x) squeezes the whole line into 0..1. Its slope is never above 0.25, which is why deep sigmoid nets learned slowly."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/sigmoid_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 2 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -800; +pub const K_X_HI_C : i16 = 800; +pub const K_X_STEP_C : u8 = 10; +pub const K_X_TICKS : [5]i8 = [-8, -4, 0, 4, 8]; +pub const K_Y_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_X_C : [4]i16 = [200, 0, -400, 600]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["x = 2", "x = 0", "x = -4", "x = 6"]; +pub const SAY_ASK : str = "How does a neuron turn any number into a probability?"; +pub const SAY_X : str = "input x"; +pub const SAY_F : str = "sigmoid(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_PLOT_LABEL : str = "The sigmoid of x and its slope from -8 to 8, with a cursor you drag"; +pub const SAY_BARS_LABEL : str = "The output and the slope at x as bars from 0 to 1"; +pub const SAY_OUT : str = "probability"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_AT_ZERO : str = "slope at 0"; +pub const SAY_FAR : str = "slope at 8"; +pub const SAY_NOTE : str = "The slope is s (1 - s), computed from the output s itself. Far from 0 it is close to nothing, so a saturated sigmoid passes almost no gradient back."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/sigmoid_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_range_is_symmetric { + assert K_X_LO_C + K_X_HI_C == 0; + assert K_X_HI_C == 800; +} + +test the_axis_spans_zero_to_one { + assert K_Y_TICKS_C[0] == 0; + assert K_Y_TICKS_C[4] == 100; + assert K_PRESET_X_C[1] == 0; +} diff --git a/apps/website/specs/widgets/nn-silu.t27 b/apps/website/specs/widgets/nn-silu.t27 new file mode 100644 index 0000000000..087ee92a09 --- /dev/null +++ b/apps/website/specs/widgets/nn-silu.t27 @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-silu.t27 -- Swish and SiLU: one knob between a smooth curve and ReLU +; Source of truth for public/widgets/nn-silu/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-silu/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/silu_swish_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 5 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -5 to 5 and sets beta from 0.25 to 8. The green curve is +; forward(x, beta), the dotted one forward(x, 1), SiLU, and the dashed one derivative(x, beta). + +; WHAT IT DOES NOT CLAIM: the claim that large beta approaches ReLU is what the curves show on this +; window, not a limit taken here. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_silu; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-silu"; +pub const TITLE : str = "Swish: one knob between a smooth curve and ReLU"; +pub const DESCRIPTION : str = "Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2."; +pub const IMAGE_ALT : str = "Swish card at beta 1, x = -1.28: the green curve dips to -0.2785 and then rises along the diagonal, over a dotted violet SiLU reference that matches it; the dashed gold slope crosses zero at the cursor. Tiles read output -0.2785, slope -0.0003, SiLU -0.2785 and the spec batch (-2, 0, 2) as -0.238 0.000 1.762."; +pub const HOOK : str = "SiLU(-1.28) = -0.2785, its lowest point. At beta 8 the dip shrinks to almost nothing and the curve is ReLU with rounded corners."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/silu_swish_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 5 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -500; +pub const K_X_HI_C : i16 = 500; +pub const K_X_STEP_C : u8 = 2; +pub const K_Y_LO_C : i16 = -100; +pub const K_Y_HI_C : i16 = 500; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [7]i8 = [-1, 0, 1, 2, 3, 4, 5]; +pub const K_BETA_LO_C : u8 = 25; +pub const K_BETA_HI_C : u16 = 800; +pub const K_BETA_STEP_C : u8 = 25; +pub const K_FIXTURE_C : [3]i16 = [-200, 0, 200]; +pub const K_PRESET_X_C : [4]i16 = [-128, -128, 200, 200]; +pub const K_PRESET_BETA_C : [4]u16 = [100, 400, 50, 800]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["SiLU at its dip", "beta 4 at the same x", "beta 0.5 at x = 2", "beta 8 at x = 2"]; +pub const SAY_ASK : str = "Is there one knob between a smooth curve and ReLU?"; +pub const SAY_X : str = "input x"; +pub const SAY_BETA : str = "beta"; +pub const SAY_F : str = "x sigmoid(beta x)"; +pub const SAY_SILU : str = "SiLU, beta 1"; +pub const SAY_DF : str = "slope"; +pub const SAY_PLOT_LABEL : str = "Swish of x for the chosen beta, SiLU for reference, and the slope"; +pub const SAY_OUT : str = "output"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_SILU_AT : str = "SiLU at x"; +pub const SAY_BATCH : str = "spec batch -2 0 2"; +pub const SAY_NOTE : str = "Swish multiplies x by a sigmoid gate of itself. beta sets how sharp the gate is: the same unit can be gentle or close to a switch."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/silu_swish_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test beta_one_is_silu { + assert K_PRESET_BETA_C[0] == 100; + assert K_BETA_LO_C < K_PRESET_BETA_C[0]; + assert K_PRESET_BETA_C[3] == K_BETA_HI_C; +} + +test the_presets_stay_in_range { + assert K_PRESET_X_C[0] >= K_X_LO_C; + assert K_PRESET_X_C[3] <= K_X_HI_C; + assert K_BETA_HI_C % K_BETA_STEP_C == 0; +} diff --git a/apps/website/specs/widgets/nn-softmax.t27 b/apps/website/specs/widgets/nn-softmax.t27 new file mode 100644 index 0000000000..09d52e7cde --- /dev/null +++ b/apps/website/specs/widgets/nn-softmax.t27 @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-softmax.t27 -- softmax and temperature: scores into a choice +; Source of truth for public/widgets/nn-softmax/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-softmax/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/softmax.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 7 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader sets three scores from -3 to 3 and a temperature from 0.1 to 5. The bars +; are softmax_at(a, b, c, T, i) and the sweep draws the same fn over T, with a cursor to drag. + +; WHAT IT DOES NOT CLAIM: three scores stand for a layer of any width; the spec's softmax_at takes +; three. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_softmax; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-softmax"; +pub const TITLE : str = "Softmax: how a network turns scores into a choice"; +pub const DESCRIPTION : str = "Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out."; +pub const IMAGE_ALT : str = "Softmax card: scores 1, 2 and 3 at temperature 1. Three bars in cyan, pink and green stand at 0.0900, 0.2447 and 0.6652. Below, three curves sweep the temperature from 0.1 to 5: the green one falls from 1 toward 0.4 while the other two rise, with a cursor at T = 1."; +pub const HOOK : str = "Scores 1, 2, 3 give 0.090, 0.245, 0.665. At temperature 0.5 the top one takes 0.867; at 5 the three are 0.27, 0.33, 0.40."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/softmax.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 7 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_SCORE_LO_C : i16 = -300; +pub const K_SCORE_HI_C : i16 = 300; +pub const K_T_LO_C : u8 = 10; +pub const K_T_HI_C : u16 = 500; +pub const K_T_STEP_C : u8 = 5; +pub const K_T_TICKS : [6]u8 = [0, 1, 2, 3, 4, 5]; +pub const K_P_TICKS_C : [5]u8 = [0, 25, 50, 75, 100]; +pub const K_PRESET_A_C : [4]i16 = [100, 100, 100, 200]; +pub const K_PRESET_B_C : [4]i16 = [200, 200, 200, 200]; +pub const K_PRESET_C_C : [4]i16 = [300, 300, 300, 0]; +pub const K_PRESET_T_C : [4]u16 = [100, 50, 500, 100]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["1, 2, 3 at T = 1", "1, 2, 3 at T = 0.5", "1, 2, 3 at T = 5", "A tie: 2, 2, 0"]; +pub const SAY_ASK : str = "How does a network turn scores into a choice?"; +pub const SAY_A : str = "A"; +pub const SAY_B : str = "B"; +pub const SAY_C : str = "C"; +pub const SAY_T : str = "temperature T"; +pub const SAY_BARS_LABEL : str = "The three probabilities softmax gives the three scores"; +pub const SAY_SWEEP_LABEL : str = "Each probability as the temperature goes from 0.1 to 5"; +pub const SAY_SWEEP : str = "Drag along the temperature: the same three scores, cooled and heated."; +pub const SAY_P : str = "p({0})"; +pub const SAY_COLD : str = "at T = {0}"; +pub const SAY_NOTE : str = "Softmax is exp(x / T) over the sum of all of them, with the largest score subtracted first so exp never overflows. A language model samples its next token from exactly this."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/softmax.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_temperature_stays_positive { + assert K_T_LO_C > 0; + assert K_T_HI_C == 500; + assert K_PRESET_T_C[1] < K_PRESET_T_C[0]; +} + +test the_presets_stay_in_range { + assert K_PRESET_C_C[0] == K_SCORE_HI_C; + assert K_PRESET_A_C[3] == K_PRESET_B_C[3]; + assert K_PRESET_T_C[2] == K_T_HI_C; +} diff --git a/apps/website/specs/widgets/nn-tanh.t27 b/apps/website/specs/widgets/nn-tanh.t27 new file mode 100644 index 0000000000..e842bc0f11 --- /dev/null +++ b/apps/website/specs/widgets/nn-tanh.t27 @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-tanh.t27 -- tanh and the saturated band where learning stops +; Source of truth for public/widgets/nn-tanh/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-tanh/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/activation/tanh_activation.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 3 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags x from -4 to 4. The curve is forward, the slope derivative, and +; every sampled x whose slope is under K_SAT is shaded red. + +; WHAT IT DOES NOT CLAIM: the threshold 0.1 is a choice made for the picture, not a constant of the +; spec. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_tanh; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-tanh"; +pub const TITLE : str = "tanh: where a neuron stops learning"; +pub const DESCRIPTION : str = "Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped."; +pub const IMAGE_ALT : str = "tanh card at x = 2.5: the green curve from -1 to 1, the dashed gold slope a bell peaking at 1, and two red bands on both sides where the slope is under 0.1. Tiles read tanh 0.9866, slope 0.0266 marked saturated, and the spec batch tanh(0, 1, 2) = 0 0.762 0.964."; +pub const HOOK : str = "tanh(2.5) is already 0.987 and its slope 0.027. Past about 1.8 either way the gradient is under 0.1: the band a deep net must stay out of."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/activation/tanh_activation.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 3 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_X_LO_C : i16 = -400; +pub const K_X_HI_C : i16 = 400; +pub const K_X_STEP_C : u8 = 5; +pub const K_X_TICKS : [5]i8 = [-4, -2, 0, 2, 4]; +pub const K_Y_TICKS : [3]i8 = [-1, 0, 1]; +pub const K_SAT_C : u8 = 10; +pub const K_PRESET_X_C : [4]i16 = [250, 0, 100, -300]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["x = 2.5", "x = 0", "x = 1", "x = -3"]; +pub const SAY_ASK : str = "Where does a neuron stop learning?"; +pub const SAY_X : str = "input x"; +pub const SAY_F : str = "tanh(x)"; +pub const SAY_DF : str = "slope"; +pub const SAY_SAT_BAND : str = "slope under 0.1"; +pub const SAY_PLOT_LABEL : str = "tanh of x and its slope from -4 to 4, saturated inputs shaded"; +pub const SAY_OUT : str = "tanh(x)"; +pub const SAY_GRAD : str = "slope at x"; +pub const SAY_BATCH : str = "spec batch 0 1 2"; +pub const SAY_STATE : str = "here"; +pub const SAY_SATURATED : str = "saturated"; +pub const SAY_LEARNING : str = "still learning"; +pub const SAY_NOTE : str = "Unlike the sigmoid, tanh is centred on 0 and its slope reaches 1. It still saturates: the gradient that flows back through it is multiplied by that slope."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/activation/tanh_activation.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_band_threshold_is_a_tenth { + assert K_SAT_C == 10; + assert K_SAT_C < 100; +} + +test the_presets_cover_both_regions { + assert K_PRESET_X_C[0] > 150; + assert K_PRESET_X_C[1] == 0; + assert K_PRESET_X_C[3] + 150 < 0; +} diff --git a/apps/website/specs/widgets/nn-xor.t27 b/apps/website/specs/widgets/nn-xor.t27 new file mode 100644 index 0000000000..262c463c48 --- /dev/null +++ b/apps/website/specs/widgets/nn-xor.t27 @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/widgets/nn-xor.t27 -- a 2-8-1 network learns XOR by backpropagation +; Source of truth for public/widgets/nn-xor/ (gHashTag/trinity): scripts/widget-pages-from-spec.mjs +; compiles this file, checks its constants, evaluates the tests below and writes the page; the page +; hands every constant to tool.js as window.T27_WIDGET. tool.js holds no English and NO FORMULA of +; its own: every value it draws comes from public/widgets/nn-xor/logic.js -- the fn bodies of +; gHashTag/t27 specs/ml/pathway/mlp.t27 compiled to wasm, beside its copy logic.t27. +; Lesson 20 of the course neural-networks. ASCII only (L3), English only (LANG-EN). +; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. + +; WHAT IT DOES: the reader drags the epochs from 0 to 2000. Every output is xor(epochs, 2 + c), the +; loss curve xor(e, 1) every 25 epochs and the first-epoch loss xor(e, 0): the spec trains its own +; 2-8-1 network from fixed initial weights at lr 0.05, from scratch on every call. + +; WHAT IT DOES NOT CLAIM: the grid shows the four inputs the spec exposes, not a decision region +; over the plane: the spec has no fn for a point between the corners. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module widget_nn_xor; + +pub const KIND : str = "widget-tool"; +pub const ID : str = "nn-xor"; +pub const TITLE : str = "XOR: a network learns what one neuron cannot"; +pub const DESCRIPTION : str = "A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders."; +pub const IMAGE_ALT : str = "XOR card after 2000 epochs: a 2 x 2 grid of the four cases, dark blue 0.000 on the diagonal and white 1.000 off it. Beside it a red loss curve on a log axis falls from 0.89 at epoch 1 to about 1e-13 at 2000. Tiles read first-epoch loss 0.8896, last 1.78e-13, outputs 0.00 1.00 1.00 0.00 against the targets 0 1 1 0."; +pub const HOOK : str = "One neuron cannot draw XOR. Eight hidden units can: after 2000 epochs the outputs are 0, 1, 1, 0 to within 4e-7 and the loss is 1.8e-13."; +pub const CATEGORY : str = "compiler"; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/pathway/mlp.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 20 opens this widget"]; +pub const READS_LOCAL_FILES : bool = false; +pub const SENDS_NOTHING : bool = true; + +pub const K_CARD_WIDTH : u16 = 1200; +pub const K_CARD_HEIGHT : u16 = 630; + +; --- Numbers: ranges, presets, and fixtures the spec holds (held equal by the tests below) +pub const K_EPOCHS_HI : u16 = 2000; +pub const K_CURVE_STEP : u8 = 25; +pub const K_LOG_LO : i8 = -14; +pub const K_LOG_HI : u8 = 1; +pub const K_LOG_TICKS : [5]i8 = [-12, -9, -6, -3, 0]; +pub const K_EPOCH_TICKS : [5]u16 = [0, 500, 1000, 1500, 2000]; +pub const K_CASES : [4]u8 = [0, 1, 1, 0]; +pub const K_PRESET_EPOCHS : [4]u16 = [2000, 0, 100, 500]; +pub const K_START_PRESET : u8 = 0; + +; --- Words on screen ------------------------------------------------------------------------ +pub const SAY_PRESETS_LABEL : str = "Start from"; +pub const SAY_PRESET_NAMES : [4]str = ["Trained, 2000 epochs", "Untrained", "100 epochs", "500 epochs"]; +pub const SAY_ASK : str = "Can a network learn something one neuron cannot?"; +pub const SAY_EPOCHS : str = "epochs"; +pub const SAY_A : str = "a ="; +pub const SAY_B : str = "b ="; +pub const SAY_CURVE_LABEL : str = "The training loss, log scale"; +pub const SAY_GRID_LABEL : str = "The network's answer for each input (a, b)"; +pub const SAY_LOG_NOTE : str = "log scale"; +pub const SAY_FIRST_LOSS : str = "loss, epoch 1"; +pub const SAY_LAST_LOSS : str = "loss, last epoch"; +pub const SAY_UNTRAINED : str = "not trained"; +pub const SAY_OUTPUTS : str = "outputs 00 01 10 11"; +pub const SAY_TARGETS : str = "targets"; +pub const SAY_NOTE : str = "XOR is 1 when exactly one input is 1. No straight line separates its 1s from its 0s, so one neuron fails; a hidden layer of ReLUs bends the space until one does."; +pub const SAY_SOURCE : str = "Logic: t27 spec ml/pathway/mlp.t27, compiled"; + +test the_card_is_the_share_size { + assert K_CARD_WIDTH == 1200; + assert K_CARD_HEIGHT == 630; + assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; +} + +test the_curve_steps_divide_the_run { + assert K_EPOCHS_HI % K_CURVE_STEP == 0; + assert K_EPOCHS_HI / K_CURVE_STEP == 80; +} + +test the_targets_are_xor { + assert K_CASES[0] == 0; + assert K_CASES[1] == 1; + assert K_CASES[2] == 1; + assert K_CASES[3] == 0; + assert K_PRESET_EPOCHS[0] == K_EPOCHS_HI; +} diff --git a/apps/website/src/lib/queenWidgets.generated.ts b/apps/website/src/lib/queenWidgets.generated.ts index e3cfbfac81..ec049a5412 100644 --- a/apps/website/src/lib/queenWidgets.generated.ts +++ b/apps/website/src/lib/queenWidgets.generated.ts @@ -1,12 +1,12 @@ // GENERATED by scripts/widgets-from-spec.mjs from specs/widgets/gallery.t27 -// spec sha256 0e72eea319b09e2a1d9ad2a4875f01334baf8cb056a64461be511ecf93df8cb1 +// spec sha256 1f89127fb05172d18af3b035147793a5729c85ef722609555e2e7de68d43b7eb // Do not edit: change the .t27 source and regenerate. export const QUEEN_WIDGETS = { "source": { "spec": "specs/widgets/gallery.t27", "publicSpec": "public/widgets/gallery.t27", - "sha256": "0e72eea319b09e2a1d9ad2a4875f01334baf8cb056a64461be511ecf93df8cb1", + "sha256": "1f89127fb05172d18af3b035147793a5729c85ef722609555e2e7de68d43b7eb", "schemaVersion": 1 }, "name": "t27 widgets", @@ -4555,6 +4555,465 @@ export const QUEEN_WIDGETS = { "iframe": "", "markdown": "[![A layer of three ternary neurons](https://t27.ai/widgets/tc-tiny-layer/card.png?v=3727a8a18457)](https://t27.ai/widgets/tc-tiny-layer/)" }, + { + "id": "nn-relu", + "kind": "tool", + "category": "compiler", + "hook": "max(0, x) is the whole rule, and its slope is 1 or 0. A leaky slope of 0.1 keeps a gradient alive on the negative side.", + "title": "ReLU: what a neuron does with a negative number", + "line": "Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through.", + "url": "https://t27.ai/widgets/nn-relu/", + "view": null, + "image": "https://t27.ai/widgets/nn-relu/card.png?v=d15fbb878508", + "gif": null, + "preview": "widgets/nn-relu/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![ReLU: what a neuron does with a negative number](https://t27.ai/widgets/nn-relu/card.png?v=d15fbb878508)](https://t27.ai/widgets/nn-relu/)" + }, + { + "id": "nn-sigmoid", + "kind": "tool", + "category": "compiler", + "hook": "1 / (1 + e^-x) squeezes the whole line into 0..1. Its slope is never above 0.25, which is why deep sigmoid nets learned slowly.", + "title": "Sigmoid: turn any number into a probability", + "line": "Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends.", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "view": null, + "image": "https://t27.ai/widgets/nn-sigmoid/card.png?v=cfbac761b571", + "gif": null, + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Sigmoid: turn any number into a probability](https://t27.ai/widgets/nn-sigmoid/card.png?v=cfbac761b571)](https://t27.ai/widgets/nn-sigmoid/)" + }, + { + "id": "nn-tanh", + "kind": "tool", + "category": "compiler", + "hook": "tanh(2.5) is already 0.987 and its slope 0.027. Past about 1.8 either way the gradient is under 0.1: the band a deep net must stay out of.", + "title": "tanh: where a neuron stops learning", + "line": "Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped.", + "url": "https://t27.ai/widgets/nn-tanh/", + "view": null, + "image": "https://t27.ai/widgets/nn-tanh/card.png?v=79db6b823fa6", + "gif": null, + "preview": "widgets/nn-tanh/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![tanh: where a neuron stops learning](https://t27.ai/widgets/nn-tanh/card.png?v=79db6b823fa6)](https://t27.ai/widgets/nn-tanh/)" + }, + { + "id": "nn-gelu", + "kind": "tool", + "category": "compiler", + "hook": "GELU(-0.75) = -0.16997 exactly and -0.17004 by the tanh form. A smooth ReLU with a small dip, used in BERT and GPT.", + "title": "GELU: why transformers bend a little below zero", + "line": "Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form.", + "url": "https://t27.ai/widgets/nn-gelu/", + "view": null, + "image": "https://t27.ai/widgets/nn-gelu/card.png?v=c2b42ff605ab", + "gif": null, + "preview": "widgets/nn-gelu/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![GELU: why transformers bend a little below zero](https://t27.ai/widgets/nn-gelu/card.png?v=c2b42ff605ab)](https://t27.ai/widgets/nn-gelu/)" + }, + { + "id": "nn-silu", + "kind": "tool", + "category": "compiler", + "hook": "SiLU(-1.28) = -0.2785, its lowest point. At beta 8 the dip shrinks to almost nothing and the curve is ReLU with rounded corners.", + "title": "Swish: one knob between a smooth curve and ReLU", + "line": "Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2.", + "url": "https://t27.ai/widgets/nn-silu/", + "view": null, + "image": "https://t27.ai/widgets/nn-silu/card.png?v=d21993bc6b54", + "gif": null, + "preview": "widgets/nn-silu/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Swish: one knob between a smooth curve and ReLU](https://t27.ai/widgets/nn-silu/card.png?v=d21993bc6b54)](https://t27.ai/widgets/nn-silu/)" + }, + { + "id": "nn-elu", + "kind": "tool", + "category": "compiler", + "hook": "ELU(-3) with alpha 1 is -0.9502, already 95% of the way to its floor of -1, and its slope there is still 0.0498, not 0.", + "title": "ELU: a negative side with a floor", + "line": "Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies.", + "url": "https://t27.ai/widgets/nn-elu/", + "view": null, + "image": "https://t27.ai/widgets/nn-elu/card.png?v=68396c794178", + "gif": null, + "preview": "widgets/nn-elu/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![ELU: a negative side with a floor](https://t27.ai/widgets/nn-elu/card.png?v=68396c794178)](https://t27.ai/widgets/nn-elu/)" + }, + { + "id": "nn-softmax", + "kind": "tool", + "category": "compiler", + "hook": "Scores 1, 2, 3 give 0.090, 0.245, 0.665. At temperature 0.5 the top one takes 0.867; at 5 the three are 0.27, 0.33, 0.40.", + "title": "Softmax: how a network turns scores into a choice", + "line": "Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out.", + "url": "https://t27.ai/widgets/nn-softmax/", + "view": null, + "image": "https://t27.ai/widgets/nn-softmax/card.png?v=694f0541a6a9", + "gif": null, + "preview": "widgets/nn-softmax/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Softmax: how a network turns scores into a choice](https://t27.ai/widgets/nn-softmax/card.png?v=694f0541a6a9)](https://t27.ai/widgets/nn-softmax/)" + }, + { + "id": "nn-embedding", + "kind": "tool", + "category": "compiler", + "hook": "A token is an index into a table, nothing more. Read token 2 twice and its row's gradient is (1 + 3, 2 + 4) = (4, 6); the other rows get 0.", + "title": "Embeddings: how a word becomes a row of numbers", + "line": "Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both.", + "url": "https://t27.ai/widgets/nn-embedding/", + "view": null, + "image": "https://t27.ai/widgets/nn-embedding/card.png?v=8fe367521243", + "gif": null, + "preview": "widgets/nn-embedding/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Embeddings: how a word becomes a row of numbers](https://t27.ai/widgets/nn-embedding/card.png?v=8fe367521243)](https://t27.ai/widgets/nn-embedding/)" + }, + { + "id": "nn-dropout", + "kind": "tool", + "category": "compiler", + "hook": "With p = 0.5, inverted dropout doubles the units it keeps while training (1, 2, 3, 4 becomes 2, 0, 6, 0) and leaves inference alone.", + "title": "Dropout: training a network with neurons switched off", + "line": "Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size.", + "url": "https://t27.ai/widgets/nn-dropout/", + "view": null, + "image": "https://t27.ai/widgets/nn-dropout/card.png?v=8a4ce725876d", + "gif": null, + "preview": "widgets/nn-dropout/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Dropout: training a network with neurons switched off](https://t27.ai/widgets/nn-dropout/card.png?v=8a4ce725876d)](https://t27.ai/widgets/nn-dropout/)" + }, + { + "id": "nn-conv", + "kind": "tool", + "category": "compiler", + "hook": "Pictures are read in patches. Here a 2 x 2 window steps by 2 over a 4 x 4 image and averages: 2.5, 4.5, 10.5, 12.5. A learned kernel comes next.", + "title": "Patches of a picture: a 2 x 2 window, averaged", + "line": "Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch.", + "url": "https://t27.ai/widgets/nn-conv/", + "view": null, + "image": "https://t27.ai/widgets/nn-conv/card.png?v=b42c26e28e28", + "gif": null, + "preview": "widgets/nn-conv/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Patches of a picture: a 2 x 2 window, averaged](https://t27.ai/widgets/nn-conv/card.png?v=b42c26e28e28)](https://t27.ai/widgets/nn-conv/)" + }, + { + "id": "nn-maxpool", + "kind": "tool", + "category": "compiler", + "hook": "On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2; their gradients land on cells 5, 6, 13 and 11 and nowhere else.", + "title": "Max pooling: what a network keeps when it shrinks a picture", + "line": "Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell.", + "url": "https://t27.ai/widgets/nn-maxpool/", + "view": null, + "image": "https://t27.ai/widgets/nn-maxpool/card.png?v=e9fe38153d4b", + "gif": null, + "preview": "widgets/nn-maxpool/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Max pooling: what a network keeps when it shrinks a picture](https://t27.ai/widgets/nn-maxpool/card.png?v=e9fe38153d4b)](https://t27.ai/widgets/nn-maxpool/)" + }, + { + "id": "nn-batchnorm", + "kind": "tool", + "category": "compiler", + "hook": "Features 1..4 and 10..40 come out identical, -1.34, -0.45, 0.45, 1.34: batch norm keeps the shape of each feature and throws away its scale.", + "title": "Batch norm: features on very different scales, made comparable", + "line": "A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference.", + "url": "https://t27.ai/widgets/nn-batchnorm/", + "view": null, + "image": "https://t27.ai/widgets/nn-batchnorm/card.png?v=859705989349", + "gif": null, + "preview": "widgets/nn-batchnorm/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Batch norm: features on very different scales, made comparable](https://t27.ai/widgets/nn-batchnorm/card.png?v=859705989349)](https://t27.ai/widgets/nn-batchnorm/)" + }, + { + "id": "nn-mse", + "kind": "tool", + "category": "compiler", + "hook": "A miss of 1 costs 1 / 3 of the mean; a miss of 2 costs 4 / 3. Squaring is what makes MSE fear large errors and shrug at small ones.", + "title": "Mean squared error: how wrong a guess is, as one number", + "line": "Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target.", + "url": "https://t27.ai/widgets/nn-mse/", + "view": null, + "image": "https://t27.ai/widgets/nn-mse/card.png?v=a23aaeb501dc", + "gif": null, + "preview": "widgets/nn-mse/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Mean squared error: how wrong a guess is, as one number](https://t27.ai/widgets/nn-mse/card.png?v=a23aaeb501dc)](https://t27.ai/widgets/nn-mse/)" + }, + { + "id": "nn-bce", + "kind": "tool", + "category": "compiler", + "hook": "Predicting 0.99 where the answer is 1 costs 0.01; predicting 0.01 costs 4.6. The cost of a confident mistake is what trains a classifier.", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "line": "Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound.", + "url": "https://t27.ai/widgets/nn-bce/", + "view": null, + "image": "https://t27.ai/widgets/nn-bce/card.png?v=8f6557e0c831", + "gif": null, + "preview": "widgets/nn-bce/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Cross-entropy: why a confident wrong answer costs so much](https://t27.ai/widgets/nn-bce/card.png?v=8f6557e0c831)](https://t27.ai/widgets/nn-bce/)" + }, + { + "id": "nn-huber", + "kind": "tool", + "category": "compiler", + "hook": "An error of 3 costs 2.5 under Huber with delta 1 and 4.5 squared. At 30 the gap is 29.5 against 450: why robust regression uses it.", + "title": "Huber loss: a loss that does not panic at an outlier", + "line": "Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square.", + "url": "https://t27.ai/widgets/nn-huber/", + "view": null, + "image": "https://t27.ai/widgets/nn-huber/card.png?v=9e8ba97cf835", + "gif": null, + "preview": "widgets/nn-huber/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Huber loss: a loss that does not panic at an outlier](https://t27.ai/widgets/nn-huber/card.png?v=9e8ba97cf835)](https://t27.ai/widgets/nn-huber/)" + }, + { + "id": "nn-sgd", + "kind": "tool", + "category": "compiler", + "hook": "lr 0.1 reaches 2.99996 in 50 steps. Add momentum 0.9 and it shoots to 5.13 first; at lr 1 it bounces between 0 and 6 for good.", + "title": "Gradient descent: how a network walks downhill", + "line": "Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever.", + "url": "https://t27.ai/widgets/nn-sgd/", + "view": null, + "image": "https://t27.ai/widgets/nn-sgd/card.png?v=09aa5d22c974", + "gif": null, + "preview": "widgets/nn-sgd/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Gradient descent: how a network walks downhill](https://t27.ai/widgets/nn-sgd/card.png?v=09aa5d22c974)](https://t27.ai/widgets/nn-sgd/)" + }, + { + "id": "nn-rmsprop", + "kind": "tool", + "category": "compiler", + "hook": "Its first step is 0.0316 whether the gradient is 0.001 or 1000. Dividing by the gradient's own size is what makes the step scale-free.", + "title": "RMSProp: a step that does not care how big the gradient is", + "line": "Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends.", + "url": "https://t27.ai/widgets/nn-rmsprop/", + "view": null, + "image": "https://t27.ai/widgets/nn-rmsprop/card.png?v=8976db28abff", + "gif": null, + "preview": "widgets/nn-rmsprop/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![RMSProp: a step that does not care how big the gradient is](https://t27.ai/widgets/nn-rmsprop/card.png?v=8976db28abff)](https://t27.ai/widgets/nn-rmsprop/)" + }, + { + "id": "nn-adam", + "kind": "tool", + "category": "compiler", + "hook": "Gradients 2, -40 and 0.5 all move their weights by exactly 0.001 on step 1. Adam reaches 3.00005 in 200 steps at lr 0.1.", + "title": "Adam: the optimizer most networks are trained with", + "line": "Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size.", + "url": "https://t27.ai/widgets/nn-adam/", + "view": null, + "image": "https://t27.ai/widgets/nn-adam/card.png?v=8fad2efe1102", + "gif": null, + "preview": "widgets/nn-adam/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Adam: the optimizer most networks are trained with](https://t27.ai/widgets/nn-adam/card.png?v=8fad2efe1102)](https://t27.ai/widgets/nn-adam/)" + }, + { + "id": "nn-backprop", + "kind": "tool", + "category": "compiler", + "hook": "With g = (1, 0.5) on inputs (1, 2, 3), the weights get 1, 2, 3 and 0.5, 1, 1.5, and the inputs get 0.5, 2, 3.5. Two products are the whole rule.", + "title": "Backpropagation: how blame flows back through a layer", + "line": "Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers.", + "url": "https://t27.ai/widgets/nn-backprop/", + "view": null, + "image": "https://t27.ai/widgets/nn-backprop/card.png?v=a8388b67dc9e", + "gif": null, + "preview": "widgets/nn-backprop/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Backpropagation: how blame flows back through a layer](https://t27.ai/widgets/nn-backprop/card.png?v=a8388b67dc9e)](https://t27.ai/widgets/nn-backprop/)" + }, + { + "id": "nn-xor", + "kind": "tool", + "category": "compiler", + "hook": "One neuron cannot draw XOR. Eight hidden units can: after 2000 epochs the outputs are 0, 1, 1, 0 to within 4e-7 and the loss is 1.8e-13.", + "title": "XOR: a network learns what one neuron cannot", + "line": "A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders.", + "url": "https://t27.ai/widgets/nn-xor/", + "view": null, + "image": "https://t27.ai/widgets/nn-xor/card.png?v=78f8c0793da2", + "gif": null, + "preview": "widgets/nn-xor/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![XOR: a network learns what one neuron cannot](https://t27.ai/widgets/nn-xor/card.png?v=78f8c0793da2)](https://t27.ai/widgets/nn-xor/)" + }, + { + "id": "nn-lamb", + "kind": "tool", + "category": "compiler", + "hook": "Weights (2, 4) take a step of 0.00447 and weights (6, 12) one of 0.01: a step is 0.001 of the layer's norm, capped at 10. That is how LAMB trains large batches.", + "title": "LAMB: one learning rate for layers of every size", + "line": "Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing.", + "url": "https://t27.ai/widgets/nn-lamb/", + "view": null, + "image": "https://t27.ai/widgets/nn-lamb/card.png?v=2ef9515d8b3c", + "gif": null, + "preview": "widgets/nn-lamb/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![LAMB: one learning rate for layers of every size](https://t27.ai/widgets/nn-lamb/card.png?v=2ef9515d8b3c)](https://t27.ai/widgets/nn-lamb/)" + }, + { + "id": "nn-rnn", + "kind": "tool", + "category": "compiler", + "hook": "A single pulse gives 0.762, 0.363, 0.180: the memory halves each step. A cell remembers, but not for long, which is the problem LSTMs solve.", + "title": "Recurrent cells: how a network remembers a moment ago", + "line": "Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up.", + "url": "https://t27.ai/widgets/nn-rnn/", + "view": null, + "image": "https://t27.ai/widgets/nn-rnn/card.png?v=0c5ff53a846f", + "gif": null, + "preview": "widgets/nn-rnn/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Recurrent cells: how a network remembers a moment ago](https://t27.ai/widgets/nn-rnn/card.png?v=0c5ff53a846f)](https://t27.ai/widgets/nn-rnn/)" + }, + { + "id": "nn-lstm", + "kind": "tool", + "category": "compiler", + "hook": "With the forget gate open (0.9975) and the input gate shut, a memory of 1 comes out as 0.9975: an LSTM can hold a value for a long time.", + "title": "LSTM gates: how a cell decides what to keep", + "line": "Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate.", + "url": "https://t27.ai/widgets/nn-lstm/", + "view": null, + "image": "https://t27.ai/widgets/nn-lstm/card.png?v=72b9d9347693", + "gif": null, + "preview": "widgets/nn-lstm/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![LSTM gates: how a cell decides what to keep](https://t27.ai/widgets/nn-lstm/card.png?v=72b9d9347693)](https://t27.ai/widgets/nn-lstm/)" + }, + { + "id": "nn-attention", + "kind": "tool", + "category": "compiler", + "hook": "Causal: position 0 reads only itself (1.000), position 1 splits 0.45 / 0.55, position 2 spreads 0.23, 0.32, 0.45. Every row is a softmax.", + "title": "Attention: how a word decides which other words to read", + "line": "Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future.", + "url": "https://t27.ai/widgets/nn-attention/", + "view": null, + "image": "https://t27.ai/widgets/nn-attention/card.png?v=8a8abc72d040", + "gif": null, + "preview": "widgets/nn-attention/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Attention: how a word decides which other words to read](https://t27.ai/widgets/nn-attention/card.png?v=8a8abc72d040)](https://t27.ai/widgets/nn-attention/)" + }, + { + "id": "nn-positions", + "kind": "tool", + "category": "compiler", + "hook": "Position 5 is (-0.959, 0.284, 0.479, 0.878, 0.050, 0.999, 0.005, 1.000). Four clocks at speeds 1, 0.1, 0.01 and 0.001 give each position its own reading.", + "title": "Positional encoding: how a transformer knows word order", + "line": "Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows.", + "url": "https://t27.ai/widgets/nn-positions/", + "view": null, + "image": "https://t27.ai/widgets/nn-positions/card.png?v=1a3bfc4fdceb", + "gif": null, + "preview": "widgets/nn-positions/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![Positional encoding: how a transformer knows word order](https://t27.ai/widgets/nn-positions/card.png?v=1a3bfc4fdceb)](https://t27.ai/widgets/nn-positions/)" + }, + { + "id": "nn-encoder", + "kind": "tool", + "category": "compiler", + "hook": "Post-norm rows come out at mean 0 and variance 1.000; pre-norm rows at variances 2.73, 3.33 and 0.96, because its last step is a residual add.", + "title": "An encoder block: what one transformer layer does", + "line": "Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not.", + "url": "https://t27.ai/widgets/nn-encoder/", + "view": null, + "image": "https://t27.ai/widgets/nn-encoder/card.png?v=ffd2cfddeda0", + "gif": null, + "preview": "widgets/nn-encoder/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![An encoder block: what one transformer layer does](https://t27.ai/widgets/nn-encoder/card.png?v=ffd2cfddeda0)](https://t27.ai/widgets/nn-encoder/)" + }, + { + "id": "nn-ppo", + "kind": "tool", + "category": "compiler", + "hook": "At r = 1.5 with advantage 1 and eps 0.2, the raw objective is 1.5 but PPO counts only 1.2. The clip is what keeps one update from breaking the policy.", + "title": "PPO: how an agent learns from reward without lurching", + "line": "Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling.", + "url": "https://t27.ai/widgets/nn-ppo/", + "view": null, + "image": "https://t27.ai/widgets/nn-ppo/card.png?v=432b62b0ecd7", + "gif": null, + "preview": "widgets/nn-ppo/index.html?embed=1", + "commands": [], + "recorded": null, + "iframe": "", + "markdown": "[![PPO: how an agent learns from reward without lurching](https://t27.ai/widgets/nn-ppo/card.png?v=432b62b0ecd7)](https://t27.ai/widgets/nn-ppo/)" + }, { "id": "wars", "kind": "tab", From 73e8a00ddef5ca9c0fd7c40e649f10d0ae639f94 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 20:43:42 +0000 Subject: [PATCH 3/5] course: neural-networks, from one neuron to a transformer block Course 10: nine modules and 27 lessons. It opens the parts the project's agents think with, as the gHashTag/t27 specs/ml specs they are written in: one neuron (ReLU, sigmoid, tanh), new bends (GELU, Swish, ELU), a layer (softmax, embeddings, dropout), pictures (pooling, max pooling, batch norm), the error (MSE, cross-entropy, Huber), downhill (SGD, RMSProp, Adam), learning (backpropagation, XOR, LAMB), memory and attention (a recurrent cell, LSTM gates, attention) and the transformer and the reward (positional encoding, an encoder block, PPO). Each lesson asks a question, opens one nn-* widget that answers it, and names the spec that computes it. Lesson 10 says plainly that it is average pooling until t27#10612 merges. The course is added last in courses.t27 (COURSE_COUNT 10, with a test that it closes the catalogue), with the Russian contract neural-networks-ru.t27 and the bundle i18n/neural-networks.ru.json; the negative control of course-from-spec.test.mjs moves from 10 to 11. Also regenerated: the learn pages (EN and RU), cards, sitemap, the course and route tables, and the menu entry. Refs #1695 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k --- apps/website/i18n/neural-networks.ru.json | 242 +++ .../public/learn/a-recurrent-cell/card.png | Bin 0 -> 45237 bytes .../public/learn/a-recurrent-cell/index.html | 265 +++ apps/website/public/learn/adam/card.png | Bin 0 -> 48073 bytes apps/website/public/learn/adam/index.html | 232 +++ .../public/learn/an-encoder-block/card.png | Bin 0 -> 51443 bytes .../public/learn/an-encoder-block/index.html | 446 +++++ .../learn/arithmetic-and-dsp/index.html | 2 +- apps/website/public/learn/attention/card.png | Bin 0 -> 57621 bytes .../website/public/learn/attention/index.html | 382 ++++ .../public/learn/backpropagation/card.png | Bin 0 -> 52110 bytes .../public/learn/backpropagation/index.html | 289 +++ .../public/learn/batch-normalisation/card.png | Bin 0 -> 50254 bytes .../learn/batch-normalisation/index.html | 280 +++ .../capstone-a-filter-on-the-board/index.html | 2 +- apps/website/public/learn/cards.json | 56 + .../public/learn/cross-entropy/card.png | Bin 0 -> 50686 bytes .../public/learn/cross-entropy/index.html | 289 +++ apps/website/public/learn/dropout/card.png | Bin 0 -> 43890 bytes apps/website/public/learn/dropout/index.html | 208 ++ apps/website/public/learn/elu/card.png | Bin 0 -> 51367 bytes apps/website/public/learn/elu/index.html | 197 ++ apps/website/public/learn/embeddings/card.png | Bin 0 -> 45216 bytes .../public/learn/embeddings/index.html | 240 +++ apps/website/public/learn/gelu/card.png | Bin 0 -> 53620 bytes apps/website/public/learn/gelu/index.html | 242 +++ .../public/learn/gradient-descent/card.png | Bin 0 -> 54133 bytes .../public/learn/gradient-descent/index.html | 239 +++ apps/website/public/learn/index.html | 2 +- .../learn/lamb-and-large-batches/card.png | Bin 0 -> 55235 bytes .../learn/lamb-and-large-batches/index.html | 321 +++ .../public/learn/learning-xor/card.png | Bin 0 -> 48383 bytes .../public/learn/learning-xor/index.html | 399 ++++ apps/website/public/learn/lstm-gates/card.png | Bin 0 -> 54767 bytes .../public/learn/lstm-gates/index.html | 400 ++++ .../website/public/learn/max-pooling/card.png | Bin 0 -> 46254 bytes .../public/learn/max-pooling/index.html | 222 +++ .../public/learn/mean-squared-error/card.png | Bin 0 -> 49431 bytes .../learn/mean-squared-error/index.html | 173 ++ apps/website/public/learn/neural-networks.t27 | 379 ++++ .../public/learn/neural-networks/card.png | Bin 0 -> 56300 bytes .../public/learn/neural-networks/index.html | 72 + .../learn/patches-of-a-picture/card.png | Bin 0 -> 52818 bytes .../learn/patches-of-a-picture/index.html | 297 +++ .../public/learn/positional-encoding/card.png | Bin 0 -> 65431 bytes .../learn/positional-encoding/index.html | 163 ++ .../public/learn/ppo-and-the-reward/card.png | Bin 0 -> 53412 bytes .../learn/ppo-and-the-reward/index.html | 272 +++ apps/website/public/learn/relu/card.png | Bin 0 -> 54887 bytes apps/website/public/learn/relu/index.html | 210 ++ apps/website/public/learn/rmsprop/card.png | Bin 0 -> 52834 bytes apps/website/public/learn/rmsprop/index.html | 174 ++ apps/website/public/learn/sitemap.xml | 56 + .../learn/softmax-and-temperature/card.png | Bin 0 -> 51069 bytes .../learn/softmax-and-temperature/index.html | 241 +++ .../public/learn/swish-and-silu/card.png | Bin 0 -> 52424 bytes .../public/learn/swish-and-silu/index.html | 210 ++ .../public/learn/tanh-and-saturation/card.png | Bin 0 -> 47974 bytes .../learn/tanh-and-saturation/index.html | 171 ++ .../public/learn/the-huber-loss/card.png | Bin 0 -> 51258 bytes .../public/learn/the-huber-loss/index.html | 169 ++ .../website/public/learn/the-sigmoid/card.png | Bin 0 -> 54034 bytes .../public/learn/the-sigmoid/index.html | 171 ++ .../public/ru/learn/a-recurrent-cell/card.png | Bin 0 -> 54378 bytes .../ru/learn/a-recurrent-cell/index.html | 265 +++ apps/website/public/ru/learn/adam/card.png | Bin 0 -> 64282 bytes apps/website/public/ru/learn/adam/index.html | 232 +++ .../public/ru/learn/an-encoder-block/card.png | Bin 0 -> 55439 bytes .../ru/learn/an-encoder-block/index.html | 446 +++++ .../ru/learn/arithmetic-and-dsp/index.html | 2 +- .../public/ru/learn/attention/card.png | Bin 0 -> 60475 bytes .../public/ru/learn/attention/index.html | 382 ++++ .../public/ru/learn/backpropagation/card.png | Bin 0 -> 57570 bytes .../ru/learn/backpropagation/index.html | 289 +++ .../ru/learn/batch-normalisation/card.png | Bin 0 -> 59224 bytes .../ru/learn/batch-normalisation/index.html | 280 +++ .../capstone-a-filter-on-the-board/index.html | 2 +- .../public/ru/learn/cross-entropy/card.png | Bin 0 -> 59257 bytes .../public/ru/learn/cross-entropy/index.html | 289 +++ apps/website/public/ru/learn/dropout/card.png | Bin 0 -> 57486 bytes .../public/ru/learn/dropout/index.html | 208 ++ apps/website/public/ru/learn/elu/card.png | Bin 0 -> 59497 bytes apps/website/public/ru/learn/elu/index.html | 197 ++ .../public/ru/learn/embeddings/card.png | Bin 0 -> 46877 bytes .../public/ru/learn/embeddings/index.html | 240 +++ apps/website/public/ru/learn/gelu/card.png | Bin 0 -> 60422 bytes apps/website/public/ru/learn/gelu/index.html | 242 +++ .../public/ru/learn/gradient-descent/card.png | Bin 0 -> 58829 bytes .../ru/learn/gradient-descent/index.html | 239 +++ apps/website/public/ru/learn/index.html | 2 +- .../ru/learn/lamb-and-large-batches/card.png | Bin 0 -> 60963 bytes .../learn/lamb-and-large-batches/index.html | 321 +++ .../public/ru/learn/learning-xor/card.png | Bin 0 -> 52748 bytes .../public/ru/learn/learning-xor/index.html | 399 ++++ .../public/ru/learn/lstm-gates/card.png | Bin 0 -> 59392 bytes .../public/ru/learn/lstm-gates/index.html | 400 ++++ .../public/ru/learn/max-pooling/card.png | Bin 0 -> 53369 bytes .../public/ru/learn/max-pooling/index.html | 222 +++ .../ru/learn/mean-squared-error/card.png | Bin 0 -> 61504 bytes .../ru/learn/mean-squared-error/index.html | 173 ++ .../public/ru/learn/neural-networks/card.png | Bin 0 -> 63356 bytes .../ru/learn/neural-networks/index.html | 72 + .../ru/learn/patches-of-a-picture/card.png | Bin 0 -> 53684 bytes .../ru/learn/patches-of-a-picture/index.html | 297 +++ .../ru/learn/positional-encoding/card.png | Bin 0 -> 69013 bytes .../ru/learn/positional-encoding/index.html | 163 ++ .../ru/learn/ppo-and-the-reward/card.png | Bin 0 -> 57788 bytes .../ru/learn/ppo-and-the-reward/index.html | 272 +++ apps/website/public/ru/learn/relu/card.png | Bin 0 -> 61864 bytes apps/website/public/ru/learn/relu/index.html | 210 ++ apps/website/public/ru/learn/rmsprop/card.png | Bin 0 -> 65587 bytes .../public/ru/learn/rmsprop/index.html | 174 ++ .../ru/learn/softmax-and-temperature/card.png | Bin 0 -> 56209 bytes .../learn/softmax-and-temperature/index.html | 241 +++ .../public/ru/learn/swish-and-silu/card.png | Bin 0 -> 58016 bytes .../public/ru/learn/swish-and-silu/index.html | 210 ++ .../ru/learn/tanh-and-saturation/card.png | Bin 0 -> 50337 bytes .../ru/learn/tanh-and-saturation/index.html | 171 ++ .../public/ru/learn/the-huber-loss/card.png | Bin 0 -> 65847 bytes .../public/ru/learn/the-huber-loss/index.html | 169 ++ .../public/ru/learn/the-sigmoid/card.png | Bin 0 -> 57067 bytes .../public/ru/learn/the-sigmoid/index.html | 171 ++ .../website/scripts/course-from-spec.test.mjs | 2 +- apps/website/specs/course/courses.t27 | 15 +- .../specs/course/neural-networks-ru.t27 | 38 + apps/website/specs/course/neural-networks.t27 | 379 ++++ apps/website/src/components/Navigation.tsx | 1 + apps/website/src/lib/course.generated.ts | 1759 ++++++++++++++++- .../website/src/lib/courseRoutes.generated.ts | 2 +- 129 files changed, 16874 insertions(+), 15 deletions(-) create mode 100644 apps/website/i18n/neural-networks.ru.json create mode 100644 apps/website/public/learn/a-recurrent-cell/card.png create mode 100644 apps/website/public/learn/a-recurrent-cell/index.html create mode 100644 apps/website/public/learn/adam/card.png create mode 100644 apps/website/public/learn/adam/index.html create mode 100644 apps/website/public/learn/an-encoder-block/card.png create mode 100644 apps/website/public/learn/an-encoder-block/index.html create mode 100644 apps/website/public/learn/attention/card.png create mode 100644 apps/website/public/learn/attention/index.html create mode 100644 apps/website/public/learn/backpropagation/card.png create mode 100644 apps/website/public/learn/backpropagation/index.html create mode 100644 apps/website/public/learn/batch-normalisation/card.png create mode 100644 apps/website/public/learn/batch-normalisation/index.html create mode 100644 apps/website/public/learn/cross-entropy/card.png create mode 100644 apps/website/public/learn/cross-entropy/index.html create mode 100644 apps/website/public/learn/dropout/card.png create mode 100644 apps/website/public/learn/dropout/index.html create mode 100644 apps/website/public/learn/elu/card.png create mode 100644 apps/website/public/learn/elu/index.html create mode 100644 apps/website/public/learn/embeddings/card.png create mode 100644 apps/website/public/learn/embeddings/index.html create mode 100644 apps/website/public/learn/gelu/card.png create mode 100644 apps/website/public/learn/gelu/index.html create mode 100644 apps/website/public/learn/gradient-descent/card.png create mode 100644 apps/website/public/learn/gradient-descent/index.html create mode 100644 apps/website/public/learn/lamb-and-large-batches/card.png create mode 100644 apps/website/public/learn/lamb-and-large-batches/index.html create mode 100644 apps/website/public/learn/learning-xor/card.png create mode 100644 apps/website/public/learn/learning-xor/index.html create mode 100644 apps/website/public/learn/lstm-gates/card.png create mode 100644 apps/website/public/learn/lstm-gates/index.html create mode 100644 apps/website/public/learn/max-pooling/card.png create mode 100644 apps/website/public/learn/max-pooling/index.html create mode 100644 apps/website/public/learn/mean-squared-error/card.png create mode 100644 apps/website/public/learn/mean-squared-error/index.html create mode 100644 apps/website/public/learn/neural-networks.t27 create mode 100644 apps/website/public/learn/neural-networks/card.png create mode 100644 apps/website/public/learn/neural-networks/index.html create mode 100644 apps/website/public/learn/patches-of-a-picture/card.png create mode 100644 apps/website/public/learn/patches-of-a-picture/index.html create mode 100644 apps/website/public/learn/positional-encoding/card.png create mode 100644 apps/website/public/learn/positional-encoding/index.html create mode 100644 apps/website/public/learn/ppo-and-the-reward/card.png create mode 100644 apps/website/public/learn/ppo-and-the-reward/index.html create mode 100644 apps/website/public/learn/relu/card.png create mode 100644 apps/website/public/learn/relu/index.html create mode 100644 apps/website/public/learn/rmsprop/card.png create mode 100644 apps/website/public/learn/rmsprop/index.html create mode 100644 apps/website/public/learn/softmax-and-temperature/card.png create mode 100644 apps/website/public/learn/softmax-and-temperature/index.html create mode 100644 apps/website/public/learn/swish-and-silu/card.png create mode 100644 apps/website/public/learn/swish-and-silu/index.html create mode 100644 apps/website/public/learn/tanh-and-saturation/card.png create mode 100644 apps/website/public/learn/tanh-and-saturation/index.html create mode 100644 apps/website/public/learn/the-huber-loss/card.png create mode 100644 apps/website/public/learn/the-huber-loss/index.html create mode 100644 apps/website/public/learn/the-sigmoid/card.png create mode 100644 apps/website/public/learn/the-sigmoid/index.html create mode 100644 apps/website/public/ru/learn/a-recurrent-cell/card.png create mode 100644 apps/website/public/ru/learn/a-recurrent-cell/index.html create mode 100644 apps/website/public/ru/learn/adam/card.png create mode 100644 apps/website/public/ru/learn/adam/index.html create mode 100644 apps/website/public/ru/learn/an-encoder-block/card.png create mode 100644 apps/website/public/ru/learn/an-encoder-block/index.html create mode 100644 apps/website/public/ru/learn/attention/card.png create mode 100644 apps/website/public/ru/learn/attention/index.html create mode 100644 apps/website/public/ru/learn/backpropagation/card.png create mode 100644 apps/website/public/ru/learn/backpropagation/index.html create mode 100644 apps/website/public/ru/learn/batch-normalisation/card.png create mode 100644 apps/website/public/ru/learn/batch-normalisation/index.html create mode 100644 apps/website/public/ru/learn/cross-entropy/card.png create mode 100644 apps/website/public/ru/learn/cross-entropy/index.html create mode 100644 apps/website/public/ru/learn/dropout/card.png create mode 100644 apps/website/public/ru/learn/dropout/index.html create mode 100644 apps/website/public/ru/learn/elu/card.png create mode 100644 apps/website/public/ru/learn/elu/index.html create mode 100644 apps/website/public/ru/learn/embeddings/card.png create mode 100644 apps/website/public/ru/learn/embeddings/index.html create mode 100644 apps/website/public/ru/learn/gelu/card.png create mode 100644 apps/website/public/ru/learn/gelu/index.html create mode 100644 apps/website/public/ru/learn/gradient-descent/card.png create mode 100644 apps/website/public/ru/learn/gradient-descent/index.html create mode 100644 apps/website/public/ru/learn/lamb-and-large-batches/card.png create mode 100644 apps/website/public/ru/learn/lamb-and-large-batches/index.html create mode 100644 apps/website/public/ru/learn/learning-xor/card.png create mode 100644 apps/website/public/ru/learn/learning-xor/index.html create mode 100644 apps/website/public/ru/learn/lstm-gates/card.png create mode 100644 apps/website/public/ru/learn/lstm-gates/index.html create mode 100644 apps/website/public/ru/learn/max-pooling/card.png create mode 100644 apps/website/public/ru/learn/max-pooling/index.html create mode 100644 apps/website/public/ru/learn/mean-squared-error/card.png create mode 100644 apps/website/public/ru/learn/mean-squared-error/index.html create mode 100644 apps/website/public/ru/learn/neural-networks/card.png create mode 100644 apps/website/public/ru/learn/neural-networks/index.html create mode 100644 apps/website/public/ru/learn/patches-of-a-picture/card.png create mode 100644 apps/website/public/ru/learn/patches-of-a-picture/index.html create mode 100644 apps/website/public/ru/learn/positional-encoding/card.png create mode 100644 apps/website/public/ru/learn/positional-encoding/index.html create mode 100644 apps/website/public/ru/learn/ppo-and-the-reward/card.png create mode 100644 apps/website/public/ru/learn/ppo-and-the-reward/index.html create mode 100644 apps/website/public/ru/learn/relu/card.png create mode 100644 apps/website/public/ru/learn/relu/index.html create mode 100644 apps/website/public/ru/learn/rmsprop/card.png create mode 100644 apps/website/public/ru/learn/rmsprop/index.html create mode 100644 apps/website/public/ru/learn/softmax-and-temperature/card.png create mode 100644 apps/website/public/ru/learn/softmax-and-temperature/index.html create mode 100644 apps/website/public/ru/learn/swish-and-silu/card.png create mode 100644 apps/website/public/ru/learn/swish-and-silu/index.html create mode 100644 apps/website/public/ru/learn/tanh-and-saturation/card.png create mode 100644 apps/website/public/ru/learn/tanh-and-saturation/index.html create mode 100644 apps/website/public/ru/learn/the-huber-loss/card.png create mode 100644 apps/website/public/ru/learn/the-huber-loss/index.html create mode 100644 apps/website/public/ru/learn/the-sigmoid/card.png create mode 100644 apps/website/public/ru/learn/the-sigmoid/index.html create mode 100644 apps/website/specs/course/neural-networks-ru.t27 create mode 100644 apps/website/specs/course/neural-networks.t27 diff --git a/apps/website/i18n/neural-networks.ru.json b/apps/website/i18n/neural-networks.ru.json new file mode 100644 index 0000000000..dc0bec6914 --- /dev/null +++ b/apps/website/i18n/neural-networks.ru.json @@ -0,0 +1,242 @@ +{ + "$spec": "specs/course/neural-networks-ru.t27", + "$note": "Russian words for specs/course/neural-networks.t27. Keys are MODULE_IDS, LESSON_IDS and, under ui, the SAY_ names. Numbers and {placeholders} must match the English field; course-from-spec.mjs checks both.", + "locale": "ru", + "ui": { + "TITLE": "Нейросети на t27: от одного нейрона до блока трансформера", + "DESCRIPTION": "Курс 10, 27 уроков, в каждом живой виджет и спека t27: функции активации, softmax и эмбеддинги, пулинг и пакетная нормализация, функции потерь, SGD, RMSProp и Adam, обратное распространение и XOR, рекуррентные ячейки, внимание, блок трансформера и PPO. Каждое число вычисляет скомпилированная спека.", + "KICKER": "Курс", + "LEAD": "Агенты этого проекта думают нейросетями, а здесь их части записаны спеками t27 с тестами, которые проверяет компилятор. Каждый виджет исполняет тела fn спеки из specs/ml, скомпилированные в WebAssembly: двигаете ползунок — отвечает спека.", + "SHAPE": "9 модулей по 3 урока, 27 клеток. Заполненная клетка — урок, отмеченный пройденным.", + "START": "Начать урок 1", + "CONTINUE": "Продолжить", + "MODULE": "Модуль {0}", + "LESSON": "Урок {0} из {1}", + "GOAL": "Вы узнаете", + "TRY": "Попробовать", + "ALSO": "Также откройте", + "ALSO_HINT": "Каждая кнопка меняет виджет сверху.", + "BACK_TO_MAIN": "Вернуться к виджету урока", + "SPEC": "Открыть спеку урока в плеере", + "OPEN_PAGE": "Открыть виджет на отдельной странице", + "WIDGET_LANG": "Виджеты хранят свои английские слова: у каждого своя спека t27.", + "PREV": "Назад", + "NEXT": "Далее", + "ALL": "Все уроки", + "MARK": "Отметить пройденным", + "MARKED": "Пройдено", + "PROGRESS": "{0} из {1} пройдено", + "PRIVATE": "Прогресс хранится только в этом браузере; ничего не отправляется.", + "SOURCE": "Этот курс сам является спекой t27: прочитайте её", + "COHORT": "Ищете платное обучение по FPGA? Оно переехало на отдельную страницу.", + "NOT_FOUND": "У урока нет такого адреса.", + "OPEN_LESSON": "Открыть интерактивный урок", + "OPEN_COURSE": "Открыть интерактивный курс", + "SEO_TITLE": "{0}: курс о нейросетях, урок {1} из {2}", + "SHARE": "Ссылка для шаринга, с карточкой предпросмотра", + "NEXT_COURSE": "Следующий курс", + "PREV_COURSE": "Предыдущий курс" + }, + "modules": { + "one-neuron": { + "TITLE": "Один нейрон", + "LINE": "Нейрон складывает входы и изгибает сумму: ReLU, сигмоида и tanh, и где каждая перестаёт пропускать градиент назад." + }, + "new-bends": { + "TITLE": "Новые изгибы", + "LINE": "Гладкие кривые нынешних моделей: GELU с провалом, Swish с ручкой и ELU с полом вместо обрыва." + }, + "a-layer": { + "TITLE": "Слой", + "LINE": "Что окружает нейроны: softmax превращает оценки в выбор, эмбеддинг превращает слово в числа, dropout выключает нейроны." + }, + "pictures": { + "TITLE": "Картинки", + "LINE": "Чтение картинки по участкам: окно, усреднённое по участку, max pooling и пакетная нормализация признаков разного масштаба." + }, + "the-error": { + "TITLE": "Ошибка", + "LINE": "Насколько неверна догадка, одним числом: среднеквадратичная ошибка, перекрёстная энтропия для вероятностей и функция Хьюбера для выбросов." + }, + "downhill": { + "TITLE": "Под гору", + "LINE": "Спуск по функции потерь: градиентный спуск с моментом, RMSProp без оглядки на величину градиента и Adam, который соединяет оба." + }, + "learning": { + "TITLE": "Обучение", + "LINE": "Откуда берутся градиенты и чего они добиваются: обратное распространение через слой, сеть, которая учит XOR, и LAMB для больших пакетов." + }, + "memory-and-attention": { + "TITLE": "Память и внимание", + "LINE": "Сети, которые читают последовательность: рекуррентная ячейка и её затухающее эхо, вентили LSTM и внимание ко всем позициям сразу." + }, + "transformer-and-reward": { + "TITLE": "Трансформер и награда", + "LINE": "Части трансформера и агента: позиции как часы, один блок энкодера и PPO, который учится на награде без рывков." + } + }, + "lessons": { + "relu": { + "TITLE": "ReLU: оставить положительную часть", + "GOAL": "Что ReLU делает с положительным и с отрицательным входом и почему наклон 0 останавливает обучение нейрона.", + "TEXT": "Нейрон складывает взвешенные входы и пропускает сумму через функцию активации. ReLU из них самая простая, max(0, x): положительная сумма проходит без изменений, отрицательная становится 0. Её наклон равен 1 или 0, а наклон 0 означает нейрон, который перестал учиться: градиент через него назад не течёт. Утечка это исправляет: с наклоном 0.1 вход x = -2 даёт -0.2 и пропускает назад градиент 0.1. Спека relu_activation.t27 вычисляет обе кривые, которые рисует виджет.", + "TASK": "Поставьте x на -2 и прочитайте наклон с утечкой и без неё; затем найдите наклон при x = 1.5." + }, + "the-sigmoid": { + "TITLE": "Сигмоида: число в вероятность", + "GOAL": "Как сигмоида переводит любой вход в вероятность и почему её наклон мешает глубоким сетям.", + "TEXT": "Сигмоида 1 / (1 + e^-x) сжимает всю числовую прямую в отрезок от 0 до 1, поэтому её читают как вероятность: 2 превращается в 0.8808, а -4 в 0.018. Её наклон равен s (1 - s) и считается по самому выходу s; он наибольший в 0, где равен 0.25, а при x = 8 равен 0.000335. Градиент, который идёт назад через стопку сигмоид, на каждой умножается не больше чем на 0.25, поэтому глубокие сети на сигмоидах учились медленно. Спека sigmoid_activation.t27 вычисляет кривую и наклон.", + "TASK": "Найдите вход, при котором вероятность равна 0.5; затем перетащите к 6 и посмотрите, как мало осталось наклона." + }, + "tanh-and-saturation": { + "TITLE": "tanh и насыщение", + "GOAL": "Почему tanh центрирована на нуле и где её наклон падает так низко, что нейрон перестаёт учиться.", + "TEXT": "tanh это сигмоида, растянутая на -1..1 и центрированная на 0, поэтому слой нейронов tanh передаёт дальше значения со средним около нуля, а её наклон в центре достигает 1. Она тоже насыщается: при 2.5 выход 0.9866, а наклон всего 0.0266. Красная полоса отмечает все входы, где наклон меньше 0.1, дальше примерно 1.8 в обе стороны, и нейрон, чьи входы живут там, почти не учится. Спека tanh_activation.t27 вычисляет кривую, наклон и свой пакет, tanh от 0, 1 и 2: 0, 0.762 и 0.964.", + "TASK": "Тяните x, пока не начнётся полоса, и прочитайте наклон там; затем сравните наклон в 0 и при 2.5." + }, + "gelu": { + "TITLE": "GELU: провал ниже нуля", + "GOAL": "Что вычисляет GELU, почему она проваливается ниже нуля и насколько близко подходит её приближение через tanh.", + "TEXT": "GELU взвешивает x вероятностью того, что стандартная нормальная величина меньше него: GELU(x) = x Phi(x). Большой положительный вход проходит, большой отрицательный исчезает, а между ними кривая проваливается примерно до -0.17 около x = -0.75 и только потом растёт. BERT и GPT используют её в своих слоях прямого распространения. Точной форме нужна erf, и спека вычисляет её приближением Абрамовица-Стиган с точностью 1.5e-7, а также вычисляет приближение через tanh: при -0.75 они дают -0.16997 и -0.17004. Спека gelu_activation.t27 вычисляет обе кривые и их наклоны.", + "TASK": "Найдите нижнюю точку кривой по её наклону; затем сравните точную форму и форму через tanh при -3." + }, + "swish-and-silu": { + "TITLE": "Swish и SiLU", + "GOAL": "Как x, умноженный на sigmoid(beta x), открывает сам себя и как один параметр переводит его от гладкой кривой к ReLU.", + "TEXT": "Swish это x, умноженный на sigmoid(beta x): нейрон, который сам себе вентиль. При beta 1 он называется SiLU, и его нижняя точка -0.2785 около x = -1.28. Увеличьте beta, и вентиль становится резче: при beta 8 кривая это ReLU со скруглёнными углами, при beta 0.5 пологий склон через ноль. Один параметр переводит нейрон от гладкой кривой к переключателю, и сеть может его выучить. Спека silu_swish_activation.t27 вычисляет кривую и её наклон при любом beta, а также свой пакет при -2, 0 и 2: -0.238, 0 и 1.762.", + "TASK": "Держите x на -1.28 и поднимайте beta от 1 до 8; затем найдите beta, при котором провал на этом масштабе исчезает." + }, + "elu": { + "TITLE": "ELU: пол, а не обрыв", + "GOAL": "Как ELU сохраняет мягкую отрицательную сторону с полом на -alpha и почему её наклон никогда не умирает до конца.", + "TEXT": "ELU сохраняет положительную сторону ReLU и заменяет обрыв на отрицательной стороне кривой alpha (e^x - 1), которая выполаживается к -alpha. При alpha 1 вход x = -3 даёт -0.9502, уже близко к полу -1, а наклон там 0.0498: мал, но не 0, так что нейрон ещё может сдвинуться. Отрицательные выходы не выбрасываются, поэтому среднее выходов слоя ближе к 0. Спека elu_activation.t27 вычисляет кривую, наклон и пол, а также свой пакет при -1, 0 и 2: -0.632, 0 и 2.", + "TASK": "Поставьте alpha на 0.5 и прочитайте пол; затем найдите, как далеко влево должен уйти x, чтобы наклон стал меньше 0.01." + }, + "softmax-and-temperature": { + "TITLE": "Softmax и температура", + "GOAL": "Как softmax превращает оценки в вероятности с суммой один и что с ними делает температура.", + "TEXT": "Классификатор заканчивается одной оценкой на класс, и softmax превращает оценки в вероятности: exp каждой оценки, делённая на сумму всех. Оценки 1, 2 и 3 становятся 0.090, 0.245 и 0.665. Если сначала разделить оценки на температуру, меняется уверенность: при 0.5 верхняя оценка забирает 0.867, при 5 все три равны 0.27, 0.33 и 0.40. Языковая модель выбирает следующий токен именно отсюда, и настройка температуры чат-модели это и есть T. Спека softmax.t27 сначала вычитает наибольшую оценку, поэтому exp никогда не переполняется.", + "TASK": "Охладите температуру до 0.1 и прочитайте три вероятности; затем сделайте ничью и нагрейте её." + }, + "embeddings": { + "TITLE": "Эмбеддинги", + "GOAL": "Как токен превращается в строку чисел и почему обучение меняет только прочитанные строки.", + "TEXT": "Сеть не умеет умножать слово, поэтому каждый токен это индекс в таблице с одной строкой чисел на токен, а поиск токена копирует его строку. В спеке в таблице 4 токена шириной 2, и строка v хранит (10 v, 10 v + 1), так что токен 2 читает (20, 21). Обучение отправляет градиент назад только в прочитанные строки, а токен, прочитанный дважды, собирает оба: строки градиента (1, 2) и (3, 4) на токене 2 складываются в (4, 6). Спека embedding_layer.t27 вычисляет поиск и градиент.", + "TASK": "Прочитайте токен 2 дважды, а затем токены 1 и 3; каждый раз сосчитайте строки, где градиент не 0." + }, + "dropout": { + "TITLE": "Dropout: выключенные нейроны", + "GOAL": "Почему выключение нейронов во время обучения помогает и почему выживших нужно масштабировать.", + "TEXT": "Во время обучения dropout случайно выключает долю p нейронов, чтобы остальные не опирались ни на один из них. Выжившие нейроны тогда нужно масштабировать, иначе следующий слой видел бы сигнал другого размера при обучении, чем при выводе. Обратный dropout умножает их на 1 / (1 - p) при обучении: с p = 0.5 вход 1, 2, 3, 4 становится 2, 0, 6, 0, а вывод это простой проход. Классический dropout оставляет 1, 0, 3, 0 и умножает на 0.5 уже при выводе. Спека dropout_layer.t27 использует фиксированную маску, оставить, выбросить, оставить, выбросить, поэтому числа каждый раз одинаковые.", + "TASK": "Сравните выходы четырёх режимов; затем прочитайте градиент выброшенного нейрона при обучении." + }, + "patches-of-a-picture": { + "TITLE": "Участки картинки", + "GOAL": "Почему сети читают картинку по участкам и что даёт окно 2 x 2, усреднённое по каждому участку.", + "TEXT": "Картинка это сетка чисел, и сети читают её небольшими участками, чтобы один и тот же детектор работал в любом её месте. Здесь окно 2 x 2 шагает по 2 по картинке 4 x 4, где в клетке i лежит i, и каждый выход это среднее своего участка: 2.5, 4.5, 10.5 и 12.5. При обратном проходе градиент каждого выхода делится поровну на его 4 клетки. Это усредняющий пулинг: свёртка взвешивала бы 4 клетки выученным ядром, и её спека, t27#10612, ещё не слита. Спека avgpool2d_layer.t27 вычисляет оба прохода.", + "TASK": "Нажмите на каждый участок и проверьте его среднее на глаз; затем включите градиент и прочитайте, что получает каждая клетка окна 4." + }, + "max-pooling": { + "TITLE": "Max pooling: максимум окна", + "GOAL": "Что оставляет max pooling, откуда, как он помнит, это взято и куда идёт градиент.", + "TEXT": "Max pooling оставляет наибольшее значение каждого окна и отбрасывает остальные, поэтому сети становится менее важно, где именно лежит признак. На сетке спеки 4 x 4 окна 2 x 2 с шагом 2 оставляют 4, 8, 9 и -2, взятые из клеток 5, 6, 13 и 11. Перекрывающиеся окна 3 x 3 с шагом 1 оставляют 8, 8, 9 и 9. При обратном проходе весь градиент окна идёт в его максимум: градиенты 1, 2, 3 и 4 попадают в клетки 5, 6, 13 и 11, а все остальные клетки получают 0. Спека maxpool2d_layer.t27 вычисляет выходы, их позиции и градиент.", + "TASK": "Переключитесь на окна 3 x 3 и найдите клетку, общую для двух выходов; затем включите градиент для окон 2 x 2." + }, + "batch-normalisation": { + "TITLE": "Пакетная нормализация", + "GOAL": "Как пакетная нормализация приводит признаки разного масштаба к одному и чем она пользуется при выводе.", + "TEXT": "Признаки разного масштаба дёргают сеть: в пакете спеки один признак в десять раз больше другого. Пакетная нормализация вычитает среднее каждого признака по пакету и делит на его разброс, поэтому признаки 1, 2, 3, 4 и 10, 20, 30, 40 оба выходят как -1.34, -0.45, 0.45 и 1.34, а -1, -1, 1, 1 выходит как -1 и 1. Затем выученные gamma и beta масштабируют и сдвигают его обратно, где это полезно. При выводе слой вместо пакета использует скользящие средние: при среднем 0, дисперсии 1, gamma 1 и beta 0.25 входы 1, 2 и 3 дают 1.25, 2.25 и 3.25. Спека batchnorm_layer.t27 вычисляет оба режима.", + "TASK": "Сравните два нормализованных столбца; затем поставьте скользящее среднее 2 и дисперсию 4 и прочитайте выходы вывода." + }, + "mean-squared-error": { + "TITLE": "Среднеквадратичная ошибка", + "GOAL": "Как MSE превращает каждый промах в одно число, почему она гоняется за большими ошибками и куда смотрит её градиент.", + "TEXT": "Функция потерь превращает все промахи модели в одно число, которое нужно уменьшать. Среднеквадратичная ошибка усредняет квадраты промахов: предсказания 1.5, 2 и 2 против целей 1, 2 и 3 стоят (0.25 + 0 + 1) / 3 = 0.4167. Из-за квадрата промах на 2 стоит в 4 раза больше промаха на 1, поэтому MSE гоняется за большими ошибками. Её градиент для каждого предсказания равен 2 (p - t) / n, здесь 0.333, 0 и -0.667: каждое предсказание толкается обратно к своей цели. Как функция одного предсказания потеря это парабола, чаша с одним дном. Спека mse_loss.t27 вычисляет потерю и градиент.", + "TASK": "Передвиньте предсказание 2 на его цель и прочитайте потерю; затем ведите по чаше и найдите её дно." + }, + "cross-entropy": { + "TITLE": "Перекрёстная энтропия", + "GOAL": "Почему перекрёстная энтропия так дорого берёт за уверенный неверный ответ и почему именно это учит классификатор.", + "TEXT": "Классификатор выдаёт вероятность, а перекрёстная энтропия берёт -log вероятности, которую он дал верному ответу. Предсказания 0.8, 0.3 и 0.9 против ответов 1, 0 и 1 стоят в среднем 0.2284. Быть уверенным и правым почти бесплатно: 0.99, 0.01 и 0.99 стоят 0.0101. Быть уверенным и неправым дорого: 0.01, 0.99 и 0.01 стоят 4.6052, а к 0 стоимость растёт без предела, поэтому спека обрезает p до [1e-7, 1 - 1e-7]. Её градиент наибольший как раз там, где модель уверена и неправа. Спека binary_crossentropy_loss.t27 вычисляет потерю и градиент, из вероятностей или из логитов.", + "TASK": "Тяните предсказание 0 к 0.01 и смотрите на кривую; затем прочитайте столбики градиента при 0.5, 0.5 и 0.5." + }, + "the-huber-loss": { + "TITLE": "Функция Хьюбера", + "GOAL": "Как функция Хьюбера обходится с малой ошибкой как с квадратичной, а с большой линейно, чтобы выбросы тянули слабее.", + "TEXT": "Квадратичная ошибка позволяет одному выбросу всё решать: ошибка 3 стоит 4.5 как половина своего квадрата, столько же, сколько 36 ошибок по 0.5. Функция Хьюбера равна половине квадрата, пока |e| не больше delta, а дальше растёт только линейно, delta |e| - delta^2 / 2, так что при delta 1 та же ошибка стоит 2.5. Два куска сходятся с одинаковым значением и наклоном, и градиент никогда не превышает delta: далёкая точка тянет модель с ограниченной силой. Для пары ошибок спеки 0.5 и 3 среднее равно 1.3125 против 2.3125 для половины квадрата. Спека huber_loss.t27 вычисляет обе.", + "TASK": "Поставьте delta на 0.5 и тяните ошибку к 3; затем найдите, где две кривые расходятся." + }, + "gradient-descent": { + "TITLE": "Градиентный спуск", + "GOAL": "Как градиентный спуск идёт вниз по функции потерь, что добавляет момент и почему слишком большой шаг никогда не успокаивается.", + "TEXT": "Обучение это спуск под гору по функции потерь. Градиентный спуск каждый шаг сдвигает вес на -lr, умноженное на его градиент; в спеке потеря равна (x - 3)^2 от x = 0, и lr 0.1 доходит до 2.99996 за 50 шагов. Момент добавляет долю прошлого сдвига, что ускоряет длинный склон и перелетает острое дно: при 0.9 вес пролетает 3 примерно до 5.13 и, раскачиваясь, приходит к 3.09 после 50 шагов. Нестеров берёт градиент на шаг вперёд и качается меньше, примерно до 4.25. Слишком большой шаг никогда не успокаивается: при lr 1 вес навсегда скачет между 0 и 6. Спека sgd.t27 вычисляет каждый шаг.", + "TASK": "Найдите наибольший шаг обучения, который ещё успокаивается без момента; затем добавьте момент 0.9 и сосчитайте качания." + }, + "rmsprop": { + "TITLE": "RMSProp: шаг без масштаба", + "GOAL": "Как RMSProp делит каждый шаг на скользящий корень среднего квадрата, чтобы шаг больше не зависел от величины градиента.", + "TEXT": "Правильный размер шага зависит от величины градиента, а разные веса видят градиенты, отличающиеся в миллион раз. RMSProp хранит скользящее среднее квадрата градиента, кэш, и делит каждый шаг на его корень, поэтому у шага нет единиц: при постоянном градиенте 0.001, 0.5 или 1000 вес на шаге 1 сдвигается ровно на те же 0.0316 и идёт тем же путём, доходя до -0.0914 после 100 шагов при lr 0.01. Затухание задаёт, как медленно наполняется кэш: при 0.99 те же 100 шагов заканчиваются на -1.0261. Спека rmsprop.t27 вычисляет вес и кэш.", + "TASK": "Переключайтесь между тремя градиентами и убедитесь, что линии не двигаются; затем поднимите затухание до 0.99." + }, + "adam": { + "TITLE": "Adam: момент и масштаб", + "GOAL": "Как Adam соединяет момент со скользящим масштабом и почему поправка смещения делает шаг 1 фиксированного размера.", + "TEXT": "Adam соединяет обе идеи: m, скользящее среднее градиента, как в моменте, и v, скользящее среднее его квадрата, как в RMSProp; шаг равен lr m / sqrt(v). Оба начинают с 0 и поначалу слишком малы, поэтому Adam делит их на 1 - beta^t, и на шаге 1 это делает сдвиг ровно lr, умноженным на знак градиента: градиенты 2, -40 и 0.5 сдвигают свои веса на одинаковые 0.001. На чаше спеки (x - 3)^2 при lr 0.1 Adam поднимается от 0, перелетает примерно до 3.18 и успокаивается на 3.00005 к шагу 200. Спека adam.t27 вычисляет каждый шаг.", + "TASK": "Дайте трём градиентам очень разные размеры и прочитайте веса после шага 1; затем найдите, где путь достигает вершины." + }, + "backpropagation": { + "TITLE": "Обратное распространение", + "GOAL": "Как градиент каждого веса и каждого входа слоя следует из градиента его выходов.", + "TEXT": "Чтобы учиться, каждому весу нужно знать, как меняется потеря, когда он сдвигается. Обратное распространение отвечает по одному слою за раз: при данном g, насколько потеря хочет сдвинуть каждый выход, вес от входа i к выходу o получает g_o x_i, а вход i получает сумму по o от W[o][i] g_o и передаёт её слою ниже. При входах (1, 2, 3) и g = (1, 0.5) градиенты весов равны 1, 2, 3 и 0.5, 1, 1.5, а градиенты входов 0.5, 2 и 3.5. Слой линейный, поэтому сдвиг x0 на 1 сдвигает потерю g . y с 15.25 до 15.75, на его градиент 0.5. Спека dense_layer.t27 вычисляет все три.", + "TASK": "Поставьте g = (1, 0) и посмотрите, какие рёбра гаснут; затем поставьте g = (-2, 1) и проверьте градиенты входов вручную." + }, + "learning-xor": { + "TITLE": "Учим XOR", + "GOAL": "Почему один нейрон не может выучить XOR и как это делает скрытый слой, обученный обратным распространением.", + "TEXT": "XOR равен 1, когда ровно один из двух входов равен 1. Никакая прямая не отделяет случаи, дающие 1, от дающих 0, поэтому один нейрон выучить его не может. Скрытый слой изгибает пространство: спека обучает сеть 2-8-1 из ReLU обратным распространением, lr 0.05, из фиксированных начальных весов. Её потеря падает с 0.8896 в эпохе 1 до 1.8e-13 после 2000 эпох, а четыре ответа выходят в пределах 4e-7 от 0, 1, 1 и 0. Виджет проводит это обучение в вашем браузере, заново для каждой точки кривой. Спека mlp.t27 хранит сеть и тест, что она учится.", + "TASK": "Отведите эпохи назад к 100 и прочитайте четыре ответа; затем найдите эпоху, где кривая перестаёт падать." + }, + "lamb-and-large-batches": { + "TITLE": "LAMB и большие пакеты", + "GOAL": "Как LAMB масштабирует шаг каждого слоя его собственной нормой весов, чтобы один шаг обучения подходил слоям любого размера.", + "TEXT": "Обучение на очень больших пакетах требует большого шага обучения, а один шаг может быть слишком большим для малого слоя и слишком малым для большого. LAMB берёт обновление в духе Adam для каждого слоя и перемасштабирует его коэффициентом доверия, нормой весов слоя, ограниченной 10, делённой на норму обновления, поэтому каждый слой сдвигается на одну и ту же долю самого себя. В спеке веса (1, 2), умноженные на масштаб, делают шаг с нормой, в 0.001 раз меньшей их собственной: 0.00447 при масштабе 2, а когда норма весов переходит 10, около масштаба 4.47, шаг остаётся на 0.01. Спека lamb.t27 вычисляет обновление для одного слоя и для двух сразу.", + "TASK": "Прочитайте шаг при масштабах 1 и 2 и сравните; затем перетащите за изгиб и объясните, почему линия становится плоской." + }, + "a-recurrent-cell": { + "TITLE": "Рекуррентная ячейка", + "GOAL": "Как рекуррентная ячейка переносит состояние от шага к шагу и почему эта память затухает.", + "TEXT": "Предложение приходит по одному слову, и рекуррентная ячейка переносит состояние h от шага к шагу: h' = tanh(W_x x + W_h h + b). В крошечной ячейке спеки W_x равен 1, а W_h 0.5, поэтому один импульс даёт 0.7616, 0.3634 и 0.1797: память о нём примерно вдвое слабеет каждый шаг. Второй импульс на шаге 3 поднимает h до 0.7968, чуть выше, чем начинался одиночный импульс, потому что старая память ещё там. После 8 шагов остаётся лишь 0.0466. Это затухание и есть причина, по которой простые ячейки забывают длинный контекст. Спека rnn_cell.t27 вычисляет каждый шаг.", + "TASK": "Загрузите один импульс и прочитайте, за сколько шагов он падает ниже 0.1; затем сделайте вход чередующимся." + }, + "lstm-gates": { + "TITLE": "Вентили LSTM", + "GOAL": "Как вентили забывания, входа и выхода LSTM решают, что ячейка хранит, записывает и показывает.", + "TEXT": "Ячейка LSTM хранит отдельную память c и три вентиля, каждый это сигмоида между 0 и 1: забывание масштабирует старую память, вход впускает новое содержимое g, а выход решает, сколько памяти показать. c' = f c + i g и h' = o tanh(c'). В фикстуре спеки каждый вес равен 0, поэтому каждый вентиль это сигмоида своего смещения: при вентиле забывания 0.9975 и вентиле входа 0.0025 память 1 выходит как 0.9975, а выход равен 0.7587. Так как c проходит лишь с умножением на f, её градиент тоже переживает много шагов. Спека lstm_single.t27 вычисляет ячейку.", + "TASK": "Загрузите Remember, а затем Forget и сравните новую память; затем запишите с открытым вентилем входа." + }, + "attention": { + "TITLE": "Внимание", + "GOAL": "Как внимание сравнивает каждый запрос с каждым ключом, что даёт softmax по каждой строке и что убирает причинная маска.", + "TEXT": "Внимание позволяет каждой позиции решить, какие другие позиции читать. Каждый запрос сравнивается с каждым ключом, q . k / sqrt(d), и softmax превращает каждую строку оценок в веса с суммой 1; выход это значения, усреднённые этими весами. Две головы делают это на двух половинах вектора. С причинной маской позиция не может читать будущее: в голове 0 позиция 0 читает только себя, позиция 1 делит 0.452 и 0.548, а позиция 2 распределяет 0.230, 0.321 и 0.449. Без маски каждая строка распределяется по всем трём ключам, от 0.21 до 0.47. Спека attention_mechanism.t27 вычисляет каждый вес на своей фикстуре.", + "TASK": "Выключите и включите маску и прочитайте строку 0; затем сравните две головы в строке 2." + }, + "positional-encoding": { + "TITLE": "Позиционное кодирование", + "GOAL": "Как синусы и косинусы убывающих частот дают каждой позиции свой вектор и почему сдвиг это поворот.", + "TEXT": "Внимание видит свой вход как множество, поэтому порядок слов нужно к ним добавить. Синусоидальное кодирование даёт каждой позиции d чисел: sin и cos позиции, умноженной на частоту, которая от пары к паре падает в 10000^(2/d) раз. При d = 8 четыре пары поворачиваются на 1, 0.1, 0.01 и 0.001 радиана за позицию, как стрелки четырёх часов: позиция 5 читает -0.959, 0.284 в быстрой паре и 0.005, 1.000 в медленной. Длина каждой пары равна 1, и сдвиг на k позиций поворачивает каждую пару на свой постоянный угол. Спека positional_encoding.t27 вычисляет каждое значение.", + "TASK": "Шагните с позиции 0 на 1 и посмотрите, какие часы двигаются; затем перейдите на 37 и найдите пару, которая всё ещё смотрит вверх." + }, + "an-encoder-block": { + "TITLE": "Блок энкодера", + "GOAL": "Что один блок энкодера трансформера делает со своим входом и что меняет перенос нормализаций вперёд.", + "TEXT": "Слой трансформера это два подслоя, каждый обёрнут остаточным сложением и нормализацией слоя: самовнимание смешивает позиции, затем сеть прямого распространения ширины 8 работает с каждой позицией отдельно. В порядке post-norm из исходной статьи блок кончается нормализацией, поэтому у каждой строки выхода среднее 0 и дисперсия 1.000. Pre-norm ставит нормализации перед каждым подслоем и кончается остаточным сложением, поэтому его строки выходят с дисперсиями 2.73, 3.33 и 0.96; глубокие стопки так учатся легче, с одной нормализацией в самом верху. Спека encoder_block.t27 прогоняет один блок на 3 позициях, d_model 4 и 2 головах.", + "TASK": "Переключайтесь между post-norm и pre-norm и читайте дисперсии строк; затем найдите позицию, которую голова 1 читает больше всего." + }, + "ppo-and-the-reward": { + "TITLE": "PPO и награда", + "GOAL": "Как PPO превращает награду в обновление политики и как его обрезка не даёт одному обновлению зайти слишком далеко.", + "TEXT": "Агент учится на награде, делая хорошие действия вероятнее. PPO измеряет изменение политики отношением r новой вероятности действия к старой и умножает его на преимущество A, насколько действие превзошло ожидание. Затем он обрезает: когда r ушло больше чем на eps в ту сторону, за которую награждает A, цель становится плоской. При r = 1.5, A = 1 и eps 0.2 сырое r A равно 1.5, но PPO засчитывает 1.2, так что один пакет не может далеко сдвинуть политику. На пакете спеки, отношения 1, 1.1 и 0.9 с преимуществами 2, 1.5 и 3, потеря политики равна -2.1167. Спека ppo_clip_loss.t27 её вычисляет.", + "TASK": "Сделайте преимущество отрицательным и найдите, где кривая теперь становится плоской; затем расширьте eps до 0.5." + } + } +} diff --git a/apps/website/public/learn/a-recurrent-cell/card.png b/apps/website/public/learn/a-recurrent-cell/card.png new file mode 100644 index 0000000000000000000000000000000000000000..54d84d1caaefab9c9f01ae3fd1f2284e74383b17 GIT binary patch literal 45237 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/a-recurrent-cell/index.html b/apps/website/public/learn/a-recurrent-cell/index.html new file mode 100644 index 0000000000..0eca5288aa --- /dev/null +++ b/apps/website/public/learn/a-recurrent-cell/index.html @@ -0,0 +1,265 @@ + + + + + + +A recurrent cell: neural networks course, lesson 22 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

A recurrent cell

+

You will learn

How a recurrent cell carries a state from step to step, and why that memory fades.

+

A sentence comes one word at a time, and a recurrent cell carries a state h from one step to the next: h' = tanh(W_x x + W_h h + b). In the spec's tiny cell W_x is 1 and W_h 0.5, so a single pulse gives 0.7616, 0.3634 and 0.1797: the memory of it roughly halves each step. A second pulse at step 3 lifts h to 0.7968, a little above where the single pulse began, because the old memory is still there. After 8 steps only 0.0466 is left. That fading is why plain cells forget long contexts. The spec rnn_cell.t27 computes each step.

+

Try it

Load one pulse and read how many steps it takes to fall under 0.1; then make the input alternate.

+

Open the interactive lesson →

+
Recurrent cells: how a network remembers a moment ago
Recurrent cells: how a network remembers a moment ago ↗
+

Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up.

+

specs/ml/recurrent/rnn_cell.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Basic RNN recurrence equation | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written against undeclared `matmul`, `add`, `zeros`, `len` and `append`,
+// it applied tanh twice (h = tanh(tanh(z))), and the tests asserted
+// `result != undefined`. It is now the Elman cell,
+// h' = tanh(W_x x + W_h h + b), with W_x hidden x input and W_h hidden x hidden
+// (row-major), stepping over buffers the caller owns.
+
+module RnnCell;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_INPUT_SIZE : u32 = 128;
+    const DEFAULT_HIDDEN_SIZE : u32 = 128;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const RNNCellConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+    };
+
+    pub const RNNState = struct {
+        hidden : []f32,
+        cell : []f32,
+    };
+
+    pub const RNNParams = struct {
+        w_x : []f32,
+        w_h : []f32,
+        b : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // new_hidden[i] = tanh(sum_j W_x[i][j] x[j] + sum_k W_h[i][k] h[k] + b[i])
+    fn forward_step(input: []const f32, hidden: []const f32, params: RNNParams, config: RNNCellConfig, new_hidden: []f32) -> void {
+        var i : usize = 0;
+        while (i < config.hidden_size) {
+            var z : f32 = params.b[i];
+            var j : usize = 0;
+            while (j < config.input_size) {
+                z = z + params.w_x[i * config.input_size + j] * input[j];
+                j = j + 1;
+            }
+            var k : usize = 0;
+            while (k < config.hidden_size) {
+                z = z + params.w_h[i * config.hidden_size + k] * hidden[k];
+                k = k + 1;
+            }
+            new_hidden[i] = tanh(z);
+            i = i + 1;
+        }
+    }
+
+    // inputs: steps x input_size; outputs: steps x hidden_size, row t = h after step t.
+    // The state starts at initial_state and each step reads the previous row.
+    fn forward_sequence(inputs: []const f32, steps: usize, initial_state: []const f32, params: RNNParams, config: RNNCellConfig, outputs: []f32) -> void {
+        const n_in : usize = config.input_size;
+        const n_h : usize = config.hidden_size;
+        var t : usize = 0;
+        while (t < steps) {
+            if (t == 0) {
+                forward_step(inputs[0..n_in], initial_state, params, config, outputs[0..n_h]);
+            } else {
+                forward_step(inputs[t * n_in .. (t + 1) * n_in], outputs[(t - 1) * n_h .. t * n_h], params, config, outputs[t * n_h .. (t + 1) * n_h]);
+            }
+            t = t + 1;
+        }
+    }
+
+    // The first hidden_size entries of `buffer`, zeroed
+    fn init_state(buffer: []f32, hidden_size: u32) -> []f32 {
+        var i : usize = 0;
+        while (i < hidden_size) {
+            buffer[i] = 0.0;
+            i = i + 1;
+        }
+        return buffer[0..hidden_size];
+    }
+
+    // A 1-in, 1-hidden cell with W_x = 1, W_h = 0.5, b = 0: h' = tanh(x + 0.5 h)
+    fn tiny() -> RNNCellConfig {
+        return RNNCellConfig{ .input_size = 1, .hidden_size = 1 };
+    }
+
+    fn tiny_step(x: f32, h: f32) -> f32 {
+        var w_x : [1]f32 = [1.0];
+        var w_h : [1]f32 = [0.5];
+        var b : [1]f32 = [0.0];
+        const input : [1]f32 = [x];
+        const hidden : [1]f32 = [h];
+        var out : [1]f32 = [9.0];
+        forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &out);
+        return out[0];
+    }
+
+    // The sequence (1, 0, 0) from h = 0: h after step t
+    fn tiny_sequence(t: usize) -> f32 {
+        var w_x : [1]f32 = [1.0];
+        var w_h : [1]f32 = [0.5];
+        var b : [1]f32 = [0.0];
+        const inputs : [3]f32 = [1.0, 0.0, 0.0];
+        const h0 : [1]f32 = [0.0];
+        var outputs : [3]f32 = [9.0] ** 3;
+        forward_sequence(&inputs, 3, &h0, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &outputs);
+        return outputs[t];
+    }
+
+    // A 2-in, 2-hidden cell: h' = tanh(W_x x + W_h h + b) with W_x = [[1, -1], [0.5, 0.5]],
+    // W_h = [[0.1, 0], [0, 0.1]], b = (0, -0.5), at x = (1, 2), h = (1, -1)
+    fn wide_step(index: usize) -> f32 {
+        var w_x : [4]f32 = [1.0, -1.0, 0.5, 0.5];
+        var w_h : [4]f32 = [0.1, 0.0, 0.0, 0.1];
+        var b : [2]f32 = [0.0, -0.5];
+        const input : [2]f32 = [1.0, 2.0];
+        const hidden : [2]f32 = [1.0, -1.0];
+        var out : [2]f32 = [9.0] ** 2;
+        forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, RNNCellConfig{ .input_size = 2, .hidden_size = 2 }, &out);
+        return out[index];
+    }
+
+    fn init_len(hidden_size: u32) -> usize {
+        var buffer : [64]f32 = [9.0] ** 64;
+        const h = init_state(&buffer, hidden_size);
+        if (h[hidden_size - 1] != 0.0) {
+            return 0;
+        }
+        return h.len;
+    }
+
+    fn valid_input() -> f32 {
+        return tiny_step(1.0, 0.0);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // z = (1 - 2 + 0.1, 0.5 + 1 - 0.1 - 0.5) = (-0.9, 0.9): h' = (tanh(-0.9), tanh(0.9))
+    test forward_step_basic_case
+        given h0 = wide_step(0)
+        when h1 = wide_step(1)
+        then @abs(h0 + 0.7162979) < 0.000001 and @abs(h1 - 0.7162979) < 0.000001 and @abs(tiny_step(1.0, 0.0) - 0.7615942) < 0.000001
+
+    // The cell remembers: after the input pulse, h decays through the recurrent weight,
+    // h1 = tanh(1), h2 = tanh(0.5 h1), h3 = tanh(0.5 h2)
+    test forward_sequence_basic_case
+        given h1 = tiny_sequence(0)
+        when h3 = tiny_sequence(2)
+        then @abs(h1 - 0.7615942) < 0.000001 and @abs(tiny_sequence(1) - tanh(0.5 * h1)) < 0.000001 and @abs(h3 - tanh(0.5 * tiny_sequence(1))) < 0.000001 and h3 > 0.0 and h3 < tiny_sequence(1)
+
+    test init_state_basic_case
+        given hidden_size = 64
+        when result = init_len(hidden_size)
+        then result == hidden_size
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input_size >= 1
+    invariant rnn_cell_constraint_0
+        assert DEFAULT_INPUT_SIZE >= 1
+
+    // hidden_size >= 1
+    invariant rnn_cell_constraint_1
+        assert DEFAULT_HIDDEN_SIZE >= 1
+
+    // name: rnn_formula -- one tanh, not two: tanh(1) = 0.7615942, tanh(tanh(1)) = 0.6420
+    invariant rnn_cell_constraint_2
+        assert valid_input() > 0.76 and valid_input() < 0.77
+
+    // "Elman (1990) - Finding Structure in Time": the state carries the past forward
+    invariant rnn_cell_constraint_3
+        assert tiny_step(0.0, 1.0) > 0.0
+
+    // "Goodfellow et al. (2016) - Sequence Modeling with RNNs and LSTMs": tanh bounds the state
+    invariant rnn_cell_constraint_4
+        assert tiny_step(100.0, 1.0) <= 1.0 and tiny_step(-100.0, -1.0) >= -1.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/adam/card.png b/apps/website/public/learn/adam/card.png new file mode 100644 index 0000000000000000000000000000000000000000..319e552d58ddeab17748d1c2e1d82375309fa578 GIT binary patch literal 48073 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
jBkQ~4>gRr3F@}md{=%xV{&?2uJ5GD2V# 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/adam/index.html b/apps/website/public/learn/adam/index.html new file mode 100644 index 0000000000..e6ffb137ed --- /dev/null +++ b/apps/website/public/learn/adam/index.html @@ -0,0 +1,232 @@ + + + + + + +Adam: neural networks course, lesson 18 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Adam

+

You will learn

How Adam combines momentum with a running scale, and why its bias correction makes step 1 a fixed size.

+

Adam combines the two ideas: m, a running mean of the gradient, as in momentum, and v, a running mean of its square, as in RMSProp; the step is lr m / sqrt(v). Both start at 0 and are too small early on, so Adam divides them by 1 - beta^t, and on step 1 that makes the move exactly lr times the sign of the gradient: gradients 2, -40 and 0.5 all move their weights by 0.001. On the spec's bowl (x - 3)^2 at lr 0.1, Adam rises from 0, overshoots to about 3.18 and settles at 3.00005 by step 200. The spec adam.t27 computes every step.

+

Try it

Give the three gradients very different sizes and read the weights after step 1; then find where the path tops out.

+

Open the interactive lesson →

+
Adam: the optimizer most networks are trained with
Adam: the optimizer most networks are trained with ↗
+

Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size.

+

specs/ml/optimizer/adam.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Adam adapts learning rate per parameter | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: step only checked its gradients with an undeclared `math::is_finite`
+// and updated nothing; the tests asserted `result != undefined`. step is now
+// Adam (Kingma and Ba, 2015) with bias correction. It refuses (returns false,
+// changes nothing) when a gradient is NaN or infinite, which is what the old body
+// validated.
+
+module Adam;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_BETA1 : f32 = 0.9;
+    const DEFAULT_BETA2 : f32 = 0.999;
+    const DEFAULT_EPSILON : f32 = 1e-8;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const AdamConfig = struct {
+        learning_rate : f32,
+        beta1 : f32,
+        beta2 : f32,
+        epsilon : f32,
+        weight_decay : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // b^t for a whole t >= 0
+    fn powi(b: f32, t: u32) -> f32 {
+        var r : f32 = 1.0;
+        var n : u32 = 0;
+        while (n < t) {
+            r = r * b;
+            n = n + 1;
+        }
+        return r;
+    }
+
+    // NaN is the one value not equal to itself; inf - inf is NaN
+    fn is_finite(x: f32) -> bool {
+        return x == x and (x - x) == (x - x);
+    }
+
+    // One Adam step number t (1-based) over params, with moment buffers m and v:
+    //   g = grad + wd p
+    //   m = b1 m + (1 - b1) g          v = b2 v + (1 - b2) g^2
+    //   m_hat = m / (1 - b1^t)          v_hat = v / (1 - b2^t)
+    //   p = p - lr m_hat / (sqrt(v_hat) + eps)
+    fn step(params: []f32, grads: []const f32, m: []f32, v: []f32, t: u32, config: AdamConfig) -> bool {
+        var i : usize = 0;
+        while (i < grads.len) {
+            if (!is_finite(grads[i])) {
+                return false;
+            }
+            i = i + 1;
+        }
+        const c1 = 1.0 - powi(config.beta1, t);
+        const c2 = 1.0 - powi(config.beta2, t);
+        i = 0;
+        while (i < params.len) {
+            const g = grads[i] + config.weight_decay * params[i];
+            m[i] = config.beta1 * m[i] + (1.0 - config.beta1) * g;
+            v[i] = config.beta2 * v[i] + (1.0 - config.beta2) * g * g;
+            const m_hat = m[i] / c1;
+            const v_hat = v[i] / c2;
+            params[i] = params[i] - config.learning_rate * m_hat / (sqrt(v_hat) + config.epsilon);
+            i = i + 1;
+        }
+        return true;
+    }
+
+    fn cfg(lr: f32) -> AdamConfig {
+        return AdamConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.0 };
+    }
+
+    // which: 0 = param, 1 = m, 2 = v after one step on params (1, 2, 3) with grads (g0, g1, g2)
+    fn first_step(g0: f32, g1: f32, g2: f32, which: u8, index: usize) -> f32 {
+        var params : [3]f32 = [1.0, 2.0, 3.0];
+        const grads : [3]f32 = [g0, g1, g2];
+        var m : [3]f32 = [0.0] ** 3;
+        var v : [3]f32 = [0.0] ** 3;
+        _ = step(&params, &grads, &m, &v, 1, cfg(0.001));
+        if (which == 1) {
+            return m[index];
+        }
+        if (which == 2) {
+            return v[index];
+        }
+        return params[index];
+    }
+
+    // a / b at run time, where IEEE gives NaN for 0 / 0 and inf for 1 / 0
+    fn ratio(a: f32, b: f32) -> f32 {
+        return a / b;
+    }
+
+    fn accepts(g: f32) -> bool {
+        var params : [1]f32 = [1.0];
+        const grads : [1]f32 = [g];
+        var m : [1]f32 = [0.0];
+        var v : [1]f32 = [0.0];
+        return step(&params, &grads, &m, &v, 1, cfg(0.001)) and params[0] != 1.0;
+    }
+
+    // Minimise (x - 3)^2 from 0
+    fn descend(steps: u32) -> f32 {
+        var params : [1]f32 = [0.0];
+        var m : [1]f32 = [0.0];
+        var v : [1]f32 = [0.0];
+        var t : u32 = 1;
+        while (t <= steps) {
+            const grads : [1]f32 = [2.0 * (params[0] - 3.0)];
+            _ = step(&params, &grads, &m, &v, t, cfg(0.1));
+            t = t + 1;
+        }
+        return params[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Bias correction makes the first step lr * sign(g), whatever |g| is
+    test step_basic_case
+        given p0 = first_step(0.1, -5.0, 0.0, 0, 0)
+        when p1 = first_step(0.1, -5.0, 0.0, 0, 1)
+        then @abs(p0 - 0.999) < 0.000001 and @abs(p1 - 2.001) < 0.000001 and first_step(0.1, -5.0, 0.0, 0, 2) == 3.0
+
+    // m = 0.1 g and v = 0.001 g^2 after the first step
+    test step_with_gradients
+        given m2 = first_step(0.1, 0.2, 0.3, 1, 2)
+        when v2 = first_step(0.1, 0.2, 0.3, 2, 2)
+        then @abs(m2 - 0.03) < 0.0000001 and @abs(v2 - 0.00009) < 0.0000001
+
+    // Finite gradients are applied; NaN and inf are refused
+    test step_validates_gradients
+        given ok = accepts(1.5) and accepts(-2.3) and accepts(4.7)
+        when refused = !accepts(ratio(0.0, 0.0)) and !accepts(ratio(1.0, 0.0))
+        then ok and refused
+
+    test step_descends_a_quadratic
+        given result = descend(500)
+        then @abs(result - 3.0) < 0.01
+
+    invariant adam_betas_are_below_one
+        assert DEFAULT_BETA1 < 1.0 and DEFAULT_BETA2 < 1.0 and DEFAULT_BETA1 < DEFAULT_BETA2 and DEFAULT_EPSILON > 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/an-encoder-block/card.png b/apps/website/public/learn/an-encoder-block/card.png new file mode 100644 index 0000000000000000000000000000000000000000..1e7f4a12fd8a24babfa7ddf66319f30f95410204 GIT binary patch literal 51443 zcmeEtRaBf^(`6C@B)A2FyM^Gv-3cxUF2TKVx8M*wxHJTZ;O_3)NN|^KTpOo>>Adgv z-Ot?3%=*t=_j>xQr|VSh+Ocxv!Zf{<}zv-en zLVfW9>&0hDu`eE(N2{26U#}iT&JrBsMQ}8?Kdhyv;B6@nm_Zx9zf+lf#S?Myz+7ha zvB5NhrIy=~iPHwxUw0svd1X4sPu{u~t??IP#1{kWrlztN2+=mKT$Js>6iy|6mChJ? ztPTOFdQWTf(5V%$6Yq`l(~7r9B~*CVdF3_LKg;Pe;1%{itCJ&ijOp=p!xTgs%XLgJSEBUBOvadr-r21v2gy~jNyMa`+wDD*3-y6 zm7PyI6#pDE5hj7YOFUazwfO&;Pgpx)Mo9eYAH4%8|5rE<*FM6g%Q)#B_>S@EQE4(R z1?R3;Q~2;ovzw=KST6yG5F2~z)Cf>q_K|gDe8j7Ja>f1HeOD7w!0?cEHw^m|ZpP|E z7nN#%#0f4Sq}=KqDI03KI{mbqVf}qBb4)&BuQnAort%q}~?%I^n)((}DP8OkE<&mOI}`GZM~m3Q%g zWD2b)#Kq+`>!YJb8P3Y6wtcT-m}k0nR&ugB-S$*(L1hZL$g=y%@20Pvaga5s%q5pU zXXaLSVHW(y3S`Yr<90++^8K})-sip774*BbVk& z>E_Josq&$7t)Z}+QG07ig>EyQb{?<(xov|h_4s7PZNEP1G2l&O^XJl&PBA<8H6iZH zN&N-S<6075MsM%t@smi>2Lh4lMV8WnewX}<@p(fLALH*D9G>7x zBdf*$=2MZI9Tth~N82~2>Yf=(g03fjrZ7h^+W@D&KM)lSotIxp#U6(>?h|>E0{PEe z+>Bxy)#mxJj;f$BpM!apzicE=BLcMG)!EA6$l(FMG)5 zG(iomn|9|Lq^QAptdD-)cWDz9Nq;V$Cg|OL9U5%7kCOzleV&3|-rTF(LxkI(Q&$oD zxbt@5~BlrGNN(i>V+<_7#{z zQXuO^K$fW3{g?6BFZE+3sHh(YOG)#r?lUv8KYjq|Cg6nmgk=lCB&cvXovLX8Stb@v zhR41SayMoLIz<@avI?UtAI4j$J@DpYWJD!L(%UXZgqZ3(eEkLVo#oxEtN_w-^JLTv zkJLDvH%TeNp3uyarV>l*)b@?vX&00tn677S+K)=Rg*q;~zsYIya0TR#witcPZSbX6 z8$N7bpNNo$^SU~Gxro(RZIF>xfgTD$J%p`jF9FC{u%YvU9Z!j+tw;J-Yu

^sd8aN(9pxJ0C&AO@GYth8Om^*s~$ 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 Q@DnsSX=SN03FCMF1J>FdAOHXW literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/an-encoder-block/index.html b/apps/website/public/learn/an-encoder-block/index.html new file mode 100644 index 0000000000..f9f3164f5a --- /dev/null +++ b/apps/website/public/learn/an-encoder-block/index.html @@ -0,0 +1,446 @@ + + + + + + +An encoder block: neural networks course, lesson 26 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

An encoder block

+

You will learn

What one transformer encoder block does to its input, and what moving the norms in front changes.

+

A transformer layer is two sublayers, each wrapped in a residual add and a layer norm: self-attention mixes the positions, then a feed-forward net of width 8 works on each position alone. In the post-norm order of the original paper the block ends with a norm, so every output row has mean 0 and variance 1.000. Pre-norm puts the norms in front of each sublayer and ends on a residual add, so its rows come out at variances 2.73, 3.33 and 0.96; deep stacks train more easily that way, with one norm added at the very top. The spec encoder_block.t27 runs one block on 3 positions, d_model 4 and 2 heads.

+

Try it

Switch between post-norm and pre-norm and read the row variances; then find the position head 1 reads most.

+

Open the interactive lesson →

+
An encoder block: what one transformer layer does
An encoder block: what one transformer layer does ↗
+

Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not.

+

specs/ml/transformer/encoder_block.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Standard Transformer encoder block with residual connections | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: attention and the FFN returned their input ("in real implementation
+// ..."), forward skipped both residuals, and the tests asked only for a non-empty
+// output from undeclared `default_input()`. The block now computes the Transformer
+// encoder layer over a seq x d_model input. Attention is multi-head scaled
+// dot-product, softmax(q k^T / sqrt(d_head)) v per head, with identity projections.
+// Then come the position-wise FFN and two residual + layer-norm steps: post-norm
+// LN(x + f(x)) by default, pre-norm x + f(LN(x)) when use_pre_norm is set.
+
+module EncoderBlock;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_D_MODEL : u32 = 512;
+    const DEFAULT_N_HEADS : u32 = 8;
+    const DEFAULT_D_FF : u32 = 2048;
+    const DEFAULT_DROPOUT : f32 = 0.1;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const EncoderBlockConfig = struct {
+        d_model : u32,
+        n_heads : u32,
+        d_ff : u32,
+        dropout : f32,
+        use_pre_norm : bool,
+    };
+
+    pub const FFNWeights = struct {
+        w1 : []const f32,
+        b1 : []const f32,
+        w2 : []const f32,
+        b2 : []const f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // q, k, v and out are seq x d_model; attn_weights is n_heads x seq x seq. Head h uses
+    // columns h * d_head .. (h + 1) * d_head.
+    fn multi_head_attention(query: []const f32, key: []const f32, value: []const f32, seq: usize, n_heads: u32, d_model: u32, out: []f32, attn_weights: []f32) -> void {
+        const d_head : usize = d_model / n_heads;
+        const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d_head)));
+        var h : usize = 0;
+        while (h < n_heads) {
+            var i : usize = 0;
+            while (i < seq) {
+                const row = attn_weights[(h * seq + i) * seq .. (h * seq + i + 1) * seq];
+                var max_s : f32 = -1.0e30;
+                var j : usize = 0;
+                while (j < seq) {
+                    var dot : f32 = 0.0;
+                    var c : usize = 0;
+                    while (c < d_head) {
+                        dot = dot + query[i * d_model + h * d_head + c] * key[j * d_model + h * d_head + c];
+                        c = c + 1;
+                    }
+                    row[j] = dot * scale;
+                    max_s = @max(max_s, row[j]);
+                    j = j + 1;
+                }
+                var sum : f32 = 0.0;
+                j = 0;
+                while (j < seq) {
+                    row[j] = exp(row[j] - max_s);
+                    sum = sum + row[j];
+                    j = j + 1;
+                }
+                var c : usize = 0;
+                while (c < d_head) {
+                    var acc : f32 = 0.0;
+                    j = 0;
+                    while (j < seq) {
+                        acc = acc + row[j] / sum * value[j * d_model + h * d_head + c];
+                        j = j + 1;
+                    }
+                    out[i * d_model + h * d_head + c] = acc;
+                    c = c + 1;
+                }
+                j = 0;
+                while (j < seq) {
+                    row[j] = row[j] / sum;
+                    j = j + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    // out = W2 relu(W1 x + b1) + b2 for one row; hidden is d_ff floats of scratch.
+    // Dropout is the identity at inference, which is what this block computes.
+    fn feed_forward(input: []const f32, weights: FFNWeights, d_model: u32, d_ff: u32, hidden: []f32, out: []f32) -> void {
+        var f : usize = 0;
+        while (f < d_ff) {
+            var z : f32 = weights.b1[f];
+            var j : usize = 0;
+            while (j < d_model) {
+                z = z + weights.w1[f * d_model + j] * input[j];
+                j = j + 1;
+            }
+            hidden[f] = @max(z, 0.0);
+            f = f + 1;
+        }
+        var o : usize = 0;
+        while (o < d_model) {
+            var y : f32 = weights.b2[o];
+            f = 0;
+            while (f < d_ff) {
+                y = y + weights.w2[o * d_ff + f] * hidden[f];
+                f = f + 1;
+            }
+            out[o] = y;
+            o = o + 1;
+        }
+    }
+
+    // (x - mean) / sqrt(var + 1e-5), no learned scale or shift
+    fn layer_norm(x: []const f32, out: []f32) -> void {
+        var mean : f32 = 0.0;
+        var k : usize = 0;
+        while (k < x.len) {
+            mean = mean + x[k];
+            k = k + 1;
+        }
+        mean = mean / @as(f32, @floatFromInt(x.len));
+        var variance : f32 = 0.0;
+        k = 0;
+        while (k < x.len) {
+            variance = variance + (x[k] - mean) * (x[k] - mean);
+            k = k + 1;
+        }
+        variance = variance / @as(f32, @floatFromInt(x.len));
+        k = 0;
+        while (k < x.len) {
+            out[k] = (x[k] - mean) / sqrt(variance + 0.00001);
+            k = k + 1;
+        }
+    }
+
+    // input and out are seq x d_model. scratch needs 3 seq d_model + n_heads seq^2 + d_ff + d_model floats.
+    fn forward(input: []const f32, seq: usize, ffn: FFNWeights, config: EncoderBlockConfig, out: []f32, scratch: []f32) -> void {
+        const n : usize = seq * config.d_model;
+        const d : usize = config.d_model;
+        const normed = scratch[0..n];
+        const attn = scratch[n .. 2 * n];
+        const mid = scratch[2 * n .. 3 * n];
+        const weights = scratch[3 * n .. 3 * n + config.n_heads * seq * seq];
+        const rest = 3 * n + config.n_heads * seq * seq;
+        const hidden = scratch[rest .. rest + config.d_ff];
+        const row = scratch[rest + config.d_ff .. rest + config.d_ff + d];
+        var t : usize = 0;
+        if (config.use_pre_norm) {
+            while (t < seq) {
+                layer_norm(input[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]);
+                t = t + 1;
+            }
+            multi_head_attention(normed, normed, normed, seq, config.n_heads, config.d_model, attn, weights);
+            var k : usize = 0;
+            while (k < n) {
+                mid[k] = input[k] + attn[k];
+                k = k + 1;
+            }
+            t = 0;
+            while (t < seq) {
+                layer_norm(mid[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]);
+                feed_forward(normed[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row);
+                var c : usize = 0;
+                while (c < d) {
+                    out[t * d + c] = mid[t * d + c] + row[c];
+                    c = c + 1;
+                }
+                t = t + 1;
+            }
+            return;
+        }
+        multi_head_attention(input, input, input, seq, config.n_heads, config.d_model, attn, weights);
+        var k : usize = 0;
+        while (k < n) {
+            normed[k] = input[k] + attn[k];
+            k = k + 1;
+        }
+        t = 0;
+        while (t < seq) {
+            layer_norm(normed[t * d .. (t + 1) * d], mid[t * d .. (t + 1) * d]);
+            feed_forward(mid[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row);
+            var c : usize = 0;
+            while (c < d) {
+                normed[t * d + c] = mid[t * d + c] + row[c];
+                c = c + 1;
+            }
+            layer_norm(normed[t * d .. (t + 1) * d], out[t * d .. (t + 1) * d]);
+            t = t + 1;
+        }
+    }
+
+    // The fixture: seq 3, d_model 4, 2 heads, d_ff 8
+    fn cfg(pre_norm: bool) -> EncoderBlockConfig {
+        return EncoderBlockConfig{ .d_model = 4, .n_heads = 2, .d_ff = 8, .dropout = DEFAULT_DROPOUT, .use_pre_norm = pre_norm };
+    }
+
+    fn fixture_input(x: []f32) -> void {
+        const v : [12]f32 = [1.0, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 2.0, 1.0, 1.0, 0.0, 0.0];
+        var k : usize = 0;
+        while (k < 12) {
+            x[k] = v[k];
+            k = k + 1;
+        }
+    }
+
+    // which: 0 = out[index], 1 = attn_weights[index] of self-attention on the fixture
+    fn attention_at(which: u8, index: usize) -> f32 {
+        var x : [12]f32 = undefined;
+        fixture_input(&x);
+        var out : [12]f32 = [9.0] ** 12;
+        var weights : [18]f32 = [9.0] ** 18;
+        multi_head_attention(&x, &x, &x, 3, 2, 4, &out, &weights);
+        if (which == 0) {
+            return out[index];
+        }
+        return weights[index];
+    }
+
+    // Two keys equal: attention splits evenly and returns the mean of the values
+    fn tie_attention(index: usize) -> f32 {
+        const q : [2]f32 = [1.0, 1.0];
+        const k : [2]f32 = [2.0, 2.0];
+        const v : [2]f32 = [4.0, 10.0];
+        var out : [2]f32 = [0.0] ** 2;
+        var weights : [4]f32 = [0.0] ** 4;
+        multi_head_attention(&q, &k, &v, 2, 1, 1, &out, &weights);
+        return out[index];
+    }
+
+    fn ffn_fill(w1: []f32, b1: []f32, w2: []f32, b2: []f32) -> void {
+        var k : usize = 0;
+        while (k < 32) {
+            w1[k] = @as(f32, @floatFromInt((k * 5 + 1) % 9)) / 8.0 - 0.5;
+            w2[k] = @as(f32, @floatFromInt((k * 7 + 2) % 9)) / 8.0 - 0.5;
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 8) {
+            b1[k] = 0.1;
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 4) {
+            b2[k] = -0.1;
+            k = k + 1;
+        }
+    }
+
+    // which: 0 = out[index]; 1 = mean of row `index`; 2 = variance of row `index`
+    fn block_at(pre_norm: bool, which: u8, index: usize) -> f32 {
+        var x : [12]f32 = undefined;
+        fixture_input(&x);
+        var w1 : [32]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [32]f32 = undefined;
+        var b2 : [4]f32 = undefined;
+        ffn_fill(&w1, &b1, &w2, &b2);
+        var out : [12]f32 = [9.0] ** 12;
+        var scratch : [3 * 12 + 18 + 8 + 4]f32 = undefined;
+        forward(&x, 3, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, cfg(pre_norm), &out, &scratch);
+        if (which == 0) {
+            return out[index];
+        }
+        var mean : f32 = 0.0;
+        var c : usize = 0;
+        while (c < 4) {
+            mean = mean + out[index * 4 + c] / 4.0;
+            c = c + 1;
+        }
+        if (which == 1) {
+            return mean;
+        }
+        var variance : f32 = 0.0;
+        c = 0;
+        while (c < 4) {
+            variance = variance + (out[index * 4 + c] - mean) * (out[index * 4 + c] - mean) / 4.0;
+            c = c + 1;
+        }
+        return variance;
+    }
+
+    // FFN on row (1, 0, 0.5, -1) of the fixture weights; out[index]
+    fn ffn_at(index: usize) -> f32 {
+        var w1 : [32]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [32]f32 = undefined;
+        var b2 : [4]f32 = undefined;
+        ffn_fill(&w1, &b1, &w2, &b2);
+        const x : [4]f32 = [1.0, 0.0, 0.5, -1.0];
+        var hidden : [8]f32 = undefined;
+        var out : [4]f32 = [9.0] ** 4;
+        feed_forward(&x, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, 4, 8, &hidden, &out);
+        return out[index];
+    }
+
+    fn valid_input() -> u32 {
+        return DEFAULT_D_MODEL / DEFAULT_N_HEADS;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Every attention row is a distribution; equal keys give the mean of the values
+    test multi_head_attention_basic_case
+        given row_sum = attention_at(1, 0) + attention_at(1, 1) + attention_at(1, 2)
+        when tied = tie_attention(0)
+        then @abs(row_sum - 1.0) < 0.000001 and tied == 7.0 and tie_attention(1) == 7.0 and attention_at(0, 0) != 9.0
+
+    // Heads are independent: head 1's weights (rows 9..17) differ from head 0's
+    test multi_head_attention_heads_differ
+        given w0 = attention_at(1, 1)
+        when w1 = attention_at(1, 10)
+        then w0 != w1 and w0 > 0.0 and w1 > 0.0
+
+    // W2 relu(W1 x + b1) + b2 on the fixture row, worked by hand: (0.4125, ..., -0.178125)
+    test feed_forward_basic_case
+        given y0 = ffn_at(0)
+        when y3 = ffn_at(3)
+        then @abs(y0 - 0.4125) < 0.000001 and @abs(y3 + 0.178125) < 0.000001 and @abs(ffn_at(2) + 0.928125) < 0.000001
+
+    // Post-norm: every output row has mean 0 and variance 1
+    test forward_basic_case
+        given mean1 = block_at(false, 1, 1)
+        when var1 = block_at(false, 2, 1)
+        then @abs(mean1) < 0.00001 and @abs(var1 - 1.0) < 0.001 and @abs(block_at(false, 1, 2)) < 0.00001
+
+    // Pre-norm keeps the residual stream un-normalised, so it differs from post-norm
+    test forward_pre_norm_differs
+        given pre = block_at(true, 0, 0)
+        when post = block_at(false, 0, 0)
+        then pre != post and pre == pre
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // d_model % n_heads == 0
+    invariant encoder_block_constraint_0
+        assert DEFAULT_D_MODEL % DEFAULT_N_HEADS == 0 and cfg(false).d_model % cfg(false).n_heads == 0
+
+    // d_ff >= d_model
+    invariant encoder_block_constraint_1
+        assert DEFAULT_D_FF >= DEFAULT_D_MODEL and cfg(false).d_ff >= cfg(false).d_model
+
+    // name: encoder_block -- each head gets d_model / n_heads columns
+    invariant encoder_block_constraint_2
+        assert valid_input() == 64
+
+    // "Vaswani et al. (2017) - Attention Is All You Need": dropout is a probability
+    invariant encoder_block_constraint_3
+        assert DEFAULT_DROPOUT >= 0.0 and DEFAULT_DROPOUT < 1.0
+
+    // "Baevski et al. (2020) - Revisiting the Self-Attention": both norm placements are offered
+    invariant encoder_block_constraint_4
+        assert cfg(true).use_pre_norm and !cfg(false).use_pre_norm
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/arithmetic-and-dsp/index.html b/apps/website/public/learn/arithmetic-and-dsp/index.html index 8256bbce67..31e3971a66 100644 --- a/apps/website/public/learn/arithmetic-and-dsp/index.html +++ b/apps/website/public/learn/arithmetic-and-dsp/index.html @@ -63,7 +63,7 @@

Arithmetic and DSP on the FPGA: from the carry chain to a filter

It picks up where the buses course ends. Every widget in it runs the fn bodies of a t27 spec compiled to WebAssembly: move a slider and the spec answers.

Course 9, 27 lessons, a live widget and a t27 spec each: adders and carry chains, multipliers and the DSP48E1 slice, fixed point, CORDIC, sampling, FIR and CIC filters, the FFT, and a filter on the bench. Every number is computed by a compiled spec.

Open the interactive course →

- +

All lessons

diff --git a/apps/website/public/learn/attention/card.png b/apps/website/public/learn/attention/card.png new file mode 100644 index 0000000000000000000000000000000000000000..36d6a9a532765f79717975b85b0b26440c8854ac GIT binary patch literal 57621 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 + + + + + +Attention: neural networks course, lesson 24 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Attention

+

You will learn

How attention scores every query against every key, what a softmax over each row gives, and what the causal mask removes.

+

Attention lets each position decide which other positions to read. Every query is scored against every key, q . k / sqrt(d), and a softmax turns each row of scores into weights that sum to 1; the output is the values averaged by those weights. Two heads do it on the two halves of the vector. With a causal mask a position cannot read the future: in head 0, position 0 reads only itself, position 1 splits 0.452 and 0.548, and position 2 spreads 0.230, 0.321 and 0.449. Without the mask every row spreads over all three keys, from 0.21 to 0.47. The spec attention_mechanism.t27 computes every weight on its own fixture.

+

Try it

Turn the mask off and on and read row 0; then compare the two heads on row 2.

+

Open the interactive lesson →

+
Attention: how a word decides which other words to read
Attention: how a word decides which other words to read ↗
+

Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future.

+

specs/ml/recurrent/attention_mechanism.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Memory-efficient attention for long sequences | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: redeclared `var i` in one scope four times, called `@infinity()` and
+// `@random()` (not Zig), and indexed every row as head_dim wide inside d_model-wide
+// rows. backward also skipped the softmax Jacobian: it pushed dL/dweights straight
+// into the scores. It is now multi-head scaled dot-product attention over seq x
+// d_model rows. Head h reads columns h*hd .. (h+1)*hd, the weights are
+// heads x seq x seq, and causal masking is optional. backward is the exact
+// gradient, checked against finite differences. Dropout is carried in the config
+// and not applied: this is the inference computation.
+
+module Attention;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const NEG_INF : f32 = -1.0e30;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const AttentionConfig = struct {
+        d_model : u32,
+        num_heads : u32,
+        dropout : f32,
+        causal : bool,
+    };
+
+    pub const AttentionOutput = struct {
+        output : []f32,
+        weights : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn seq_of(query: []const f32, config: AttentionConfig) -> usize {
+        return query.len / config.d_model;
+    }
+
+    fn scale_of(config: AttentionConfig) -> f32 {
+        return 1.0 / sqrt(@as(f32, @floatFromInt(config.d_model / config.num_heads)));
+    }
+
+    fn forward(query: []const f32, key: []const f32, value: []const f32, output: []f32, weights: []f32, config: AttentionConfig) -> void {
+        const n = seq_of(query, config);
+        const d : usize = config.d_model;
+        const hd : usize = config.d_model / config.num_heads;
+        const scale = scale_of(config);
+        var h : usize = 0;
+        while (h < config.num_heads) {
+            var i : usize = 0;
+            while (i < n) {
+                const row = weights[(h * n + i) * n .. (h * n + i + 1) * n];
+                var max_s : f32 = NEG_INF;
+                var j : usize = 0;
+                while (j < n) {
+                    var score : f32 = NEG_INF;
+                    if (!(config.causal and j > i)) {
+                        score = 0.0;
+                        var k : usize = 0;
+                        while (k < hd) {
+                            score = score + query[i * d + h * hd + k] * key[j * d + h * hd + k];
+                            k = k + 1;
+                        }
+                        score = score * scale;
+                    }
+                    row[j] = score;
+                    max_s = @max(max_s, score);
+                    j = j + 1;
+                }
+                var sum : f32 = 0.0;
+                j = 0;
+                while (j < n) {
+                    row[j] = exp(row[j] - max_s);
+                    sum = sum + row[j];
+                    j = j + 1;
+                }
+                j = 0;
+                while (j < n) {
+                    row[j] = row[j] / sum;
+                    j = j + 1;
+                }
+                var k : usize = 0;
+                while (k < hd) {
+                    var acc : f32 = 0.0;
+                    j = 0;
+                    while (j < n) {
+                        acc = acc + row[j] * value[j * d + h * hd + k];
+                        j = j + 1;
+                    }
+                    output[i * d + h * hd + k] = acc;
+                    k = k + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    // dV_j += P_ij dO_i;  dP_ij = dO_i . V_j;  dS_ij = P_ij (dP_ij - sum_k P_ik dP_ik);
+    // dQ_i += scale dS_ij K_j;  dK_j += scale dS_ij Q_i  (per head; masked P_ij are 0)
+    fn backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) -> void {
+        const n = seq_of(query, config);
+        const d : usize = config.d_model;
+        const hd : usize = config.d_model / config.num_heads;
+        const scale = scale_of(config);
+        var x : usize = 0;
+        while (x < n * d) {
+            grad_query[x] = 0.0;
+            grad_key[x] = 0.0;
+            grad_value[x] = 0.0;
+            x = x + 1;
+        }
+        var h : usize = 0;
+        while (h < config.num_heads) {
+            var i : usize = 0;
+            while (i < n) {
+                const p = attn_weights[(h * n + i) * n .. (h * n + i + 1) * n];
+                var row_dot : f32 = 0.0;
+                var j : usize = 0;
+                while (j < n) {
+                    var dp : f32 = 0.0;
+                    var k : usize = 0;
+                    while (k < hd) {
+                        dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k];
+                        grad_value[j * d + h * hd + k] = grad_value[j * d + h * hd + k] + p[j] * grad_output[i * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    row_dot = row_dot + p[j] * dp;
+                    j = j + 1;
+                }
+                j = 0;
+                while (j < n) {
+                    var dp : f32 = 0.0;
+                    var k : usize = 0;
+                    while (k < hd) {
+                        dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    const ds = p[j] * (dp - row_dot) * scale;
+                    k = 0;
+                    while (k < hd) {
+                        grad_query[i * d + h * hd + k] = grad_query[i * d + h * hd + k] + ds * key[j * d + h * hd + k];
+                        grad_key[j * d + h * hd + k] = grad_key[j * d + h * hd + k] + ds * query[i * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    j = j + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    fn cfg(causal: bool, dropout: f32) -> AttentionConfig {
+        return AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = dropout, .causal = causal };
+    }
+
+    // The fixture: seq 3, d_model 4, 2 heads (columns 0-1 and 2-3); q / k / v scaled down so the
+    // softmax is not saturated. which: 0 = output, 1 = weights.
+    fn fixture(q: []f32, k: []f32, v: []f32) -> void {
+        var x : usize = 0;
+        while (x < 12) {
+            q[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            k[x] = @as(f32, @floatFromInt(x / 4 + 1)) / 4.0 - @as(f32, @floatFromInt(x % 2)) / 3.0;
+            v[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            x = x + 1;
+        }
+    }
+
+    fn forward_at(causal: bool, which: u8, index: usize) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        var out : [12]f32 = [9.0] ** 12;
+        var w : [18]f32 = [9.0] ** 18;
+        forward(&q, &k, &v, &out, &w, cfg(causal, 0.0));
+        if (which == 0) {
+            return out[index];
+        }
+        return w[index];
+    }
+
+    // L = sum_x g_x O_x with g_x = (x + 1) / 10, one entry of q, k or v moved by delta
+    // (which: 0 = q, 1 = k, 2 = v)
+    fn loss(which: u8, index: usize, delta: f32) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        if (which == 0) {
+            q[index] = q[index] + delta;
+        }
+        if (which == 1) {
+            k[index] = k[index] + delta;
+        }
+        if (which == 2) {
+            v[index] = v[index] + delta;
+        }
+        var out : [12]f32 = undefined;
+        var w : [18]f32 = undefined;
+        forward(&q, &k, &v, &out, &w, cfg(false, 0.0));
+        var total : f32 = 0.0;
+        var x : usize = 0;
+        while (x < 12) {
+            total = total + @as(f32, @floatFromInt(x + 1)) / 10.0 * out[x];
+            x = x + 1;
+        }
+        return total;
+    }
+
+    fn grad(which: u8, index: usize, dropout: f32) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        var out : [12]f32 = undefined;
+        var w : [18]f32 = undefined;
+        forward(&q, &k, &v, &out, &w, cfg(false, dropout));
+        var g : [12]f32 = undefined;
+        var x : usize = 0;
+        while (x < 12) {
+            g[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            x = x + 1;
+        }
+        var gq : [12]f32 = undefined;
+        var gk : [12]f32 = undefined;
+        var gv : [12]f32 = undefined;
+        backward(&g, &q, &k, &v, &w, &gq, &gk, &gv, cfg(false, dropout));
+        if (which == 0) {
+            return gq[index];
+        }
+        if (which == 1) {
+            return gk[index];
+        }
+        return gv[index];
+    }
+
+    fn slope(which: u8, index: usize) -> f32 {
+        return (loss(which, index, 0.001) - loss(which, index, -0.001)) / 0.002;
+    }
+
+    fn valid_input() -> u32 {
+        return cfg(false, 0.0).d_model % cfg(false, 0.0).num_heads;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Each weight row is a distribution, and each output is a weighted mean of the values
+    // (so it lies between the smallest and largest value in its column)
+    test forward_basic_case {
+        const row_sum = forward_at(false, 1, 0) + forward_at(false, 1, 1) + forward_at(false, 1, 2);
+        assert(@abs(row_sum - 1.0) < 0.000001);
+        assert(forward_at(false, 0, 0) + forward_at(false, 0, 1) + forward_at(false, 0, 2) + forward_at(false, 0, 3) > 0.0);  // computed a meaningful output
+        assert(forward_at(false, 0, 0) > 0.1 and forward_at(false, 0, 0) < 0.9);
+    }
+
+    // dQ, dK and dV against central differences of L = g . O
+    test backward_basic_case {
+        assert(@abs(grad(0, 0, 0.0) - slope(0, 0)) < 0.001);
+        assert(@abs(grad(0, 7, 0.0) - slope(0, 7)) < 0.001);
+        assert(@abs(grad(1, 5, 0.0) - slope(1, 5)) < 0.001);
+        assert(@abs(grad(2, 10, 0.0) - slope(2, 10)) < 0.001);
+        assert(grad(0, 0, 0.0) + grad(0, 1, 0.0) + grad(0, 2, 0.0) + grad(0, 3, 0.0) != 0.0);  // computed gradients
+    }
+
+    // Position 0 attends only to itself, position 1 to positions 0 and 1
+    test forward_causal_masking {
+        assert(forward_at(true, 1, 0) == 1.0);
+        assert(forward_at(true, 1, 1) == 0.0 and forward_at(true, 1, 2) == 0.0);
+        assert(forward_at(true, 1, 1 * 3 + 2) < 0.999);
+        assert(forward_at(true, 1, 1 * 3 + 2) == 0.0);
+        assert(forward_at(true, 0, 0) == 0.1);
+    }
+
+    // Dropout is not applied here (inference), so it leaves the gradients unchanged
+    test backward_dropout {
+        assert(grad(2, 3, 0.5) == grad(2, 3, 0.0));
+        assert(grad(0, 11, 0.5) == grad(0, 11, 0.0));
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // d_model % num_heads == 0
+    invariant attention_constraint_0
+        assert valid_input() == 0
+
+    // 0 <= dropout < 1
+    invariant attention_constraint_1
+        assert cfg(false, 0.5).dropout >= 0.0 and cfg(false, 0.5).dropout < 1.0
+
+    // query.shape == key.shape == value.shape: seq is read from the query
+    invariant attention_constraint_2
+        assert cfg(false, 0.0).d_model == 4
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/backpropagation/card.png b/apps/website/public/learn/backpropagation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..c03788ffecc58a3d783558579bf9a2c6383e2c62 GIT binary patch literal 52110 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�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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/backpropagation/index.html b/apps/website/public/learn/backpropagation/index.html new file mode 100644 index 0000000000..40d0d6dd43 --- /dev/null +++ b/apps/website/public/learn/backpropagation/index.html @@ -0,0 +1,289 @@ + + + + + + +Backpropagation: neural networks course, lesson 19 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Backpropagation

+

You will learn

How the gradient of each weight and each input of a layer follows from the gradient of its outputs.

+

To learn, every weight needs to know how the loss changes when it moves. Backpropagation answers one layer at a time: given g, how much the loss wants each output to move, the weight from input i to output o gets g_o x_i, and input i gets the sum over o of W[o][i] g_o, which it hands on to the layer below. With inputs (1, 2, 3) and g = (1, 0.5) the weight gradients are 1, 2, 3 and 0.5, 1, 1.5, and the input gradients 0.5, 2 and 3.5. The layer is linear, so moving x0 by 1 moves the loss g . y from 15.25 to 15.75, by its gradient 0.5. The spec dense_layer.t27 computes all three.

+

Try it

Set g = (1, 0) and read which edges go dark; then set g = (-2, 1) and check the input gradients by hand.

+

Open the interactive lesson →

+
Backpropagation: how blame flows back through a layer
Backpropagation: how blame flows back through a layer ↗
+

Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers.

+

specs/ml/layers/dense_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Row-major weight layout for cache efficiency | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward and backward were empty placeholders, the tests asserted
+// `result != undefined`, and the invariants asserted `true` over an undeclared
+// `valid_input`. Dense is now y = act(W x + b) with W row-major
+// (output_size x input_size), and backward gives the three gradients.
+
+module Dense;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const MIN_INPUT_SIZE : u32 = 1;
+    const MAX_INPUT_SIZE : u32 = 4096;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const DenseConfig = struct {
+        input_size : u32,
+        output_size : u32,
+        has_bias : bool,
+        activation : ActivationType,
+    };
+
+    pub const ActivationType = enum(u8) {
+        None,
+        ReLU,
+        GELU,
+        Sigmoid,
+        Tanh,
+        Softmax,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // relu, the one activation the tests exercise besides None
+    fn activate(z: f32, activation: ActivationType) -> f32 {
+        if (activation == ActivationType.ReLU) {
+            if (z > 0.0) {
+                return z;
+            }
+            return 0.0;
+        }
+        return z;
+    }
+
+    // output[o] = act(sum_i weights[o * in + i] * input[i] + bias[o])
+    fn forward(input: []const f32, weights: []const f32, bias: []const f32, config: DenseConfig, output: []f32) -> void {
+        var o : usize = 0;
+        while (o < config.output_size) {
+            var z : f32 = 0.0;
+            if (config.has_bias) {
+                z = bias[o];
+            }
+            var i : usize = 0;
+            while (i < config.input_size) {
+                z = z + weights[o * config.input_size + i] * input[i];
+                i = i + 1;
+            }
+            output[o] = activate(z, config.activation);
+            o = o + 1;
+        }
+    }
+
+    // For a linear layer (activation None), given dL/dy = grad_output:
+    //   grad_input[i] = sum_o W[o][i] grad_output[o]       (W^T g)
+    //   grad_weights[o][i] = grad_output[o] * input[i]      (g x^T)
+    //   grad_bias[o] = grad_output[o]
+    fn backward(grad_output: []const f32, input: []const f32, weights: []const f32, config: DenseConfig, grad_input: []f32, grad_weights: []f32, grad_bias: []f32) -> void {
+        var i : usize = 0;
+        while (i < config.input_size) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var o : usize = 0;
+        while (o < config.output_size) {
+            grad_bias[o] = grad_output[o];
+            i = 0;
+            while (i < config.input_size) {
+                grad_input[i] = grad_input[i] + weights[o * config.input_size + i] * grad_output[o];
+                grad_weights[o * config.input_size + i] = grad_output[o] * input[i];
+                i = i + 1;
+            }
+            o = o + 1;
+        }
+    }
+
+    // The fixture: 3 inputs, 2 outputs, W = [[1, 2, 3], [-1, 0, 1]], b = [0.5, -0.5]
+    fn cfg(activation: ActivationType) -> DenseConfig {
+        return DenseConfig{ .input_size = 3, .output_size = 2, .has_bias = true, .activation = activation };
+    }
+
+    fn forward_at(x0: f32, x1: f32, x2: f32, activation: ActivationType, index: usize) -> f32 {
+        const input : [3]f32 = [x0, x1, x2];
+        const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0];
+        const bias : [2]f32 = [0.5, -0.5];
+        var output : [2]f32 = [0.0] ** 2;
+        forward(&input, &weights, &bias, cfg(activation), &output);
+        return output[index];
+    }
+
+    // L = g . y for g = (g0, g1): the loss whose gradients backward computes
+    fn loss_at(x0: f32, x1: f32, x2: f32, g0: f32, g1: f32) -> f32 {
+        return g0 * forward_at(x0, x1, x2, ActivationType.None, 0) + g1 * forward_at(x0, x1, x2, ActivationType.None, 1);
+    }
+
+    // which: 0 = grad_input, 1 = grad_weights, 2 = grad_bias
+    fn backward_at(g0: f32, g1: f32, which: u8, index: usize) -> f32 {
+        const grad_output : [2]f32 = [g0, g1];
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0];
+        var grad_input : [3]f32 = [9.0] ** 3;
+        var grad_weights : [6]f32 = [9.0] ** 6;
+        var grad_bias : [2]f32 = [9.0] ** 2;
+        backward(&grad_output, &input, &weights, cfg(ActivationType.None), &grad_input, &grad_weights, &grad_bias);
+        if (which == 0) {
+            return grad_input[index];
+        }
+        if (which == 1) {
+            return grad_weights[index];
+        }
+        return grad_bias[index];
+    }
+
+    // An empty layer (no inputs, no outputs) writes nothing
+    fn empty_forward_untouched() -> bool {
+        const none : [0]f32 = [];
+        var sentinel : [1]f32 = [7.0];
+        const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None };
+        forward(&none, &none, &none, empty_cfg, &sentinel);
+        return sentinel[0] == 7.0;
+    }
+
+    fn empty_backward_untouched() -> bool {
+        const none : [0]f32 = [];
+        var sentinel : [1]f32 = [7.0];
+        const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None };
+        backward(&none, &none, &none, empty_cfg, &sentinel, &sentinel, &sentinel);
+        return sentinel[0] == 7.0;
+    }
+
+    fn valid_input() -> f32 {
+        return forward_at(1.0, 2.0, 3.0, ActivationType.None, 0);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // x = (1, 2, 3): y0 = 1 + 4 + 9 + 0.5 = 14.5, y1 = -1 + 0 + 3 - 0.5 = 1.5
+    test forward_basic_case
+        given y0 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 0)
+        when y1 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 1)
+        then y0 == 14.5 and y1 == 1.5
+
+    // ReLU clips the negative pre-activation: x = (0, 0, -1) gives y = (-2.5, -1.5) -> (0, 0)
+    test forward_relu_clips_negatives
+        given linear = forward_at(0.0, 0.0, -1.0, ActivationType.None, 0)
+        when clipped = forward_at(0.0, 0.0, -1.0, ActivationType.ReLU, 0)
+        then linear == -2.5 and clipped == 0.0 and forward_at(1.0, 2.0, 3.0, ActivationType.ReLU, 0) == 14.5
+
+    test forward_empty_input
+        given result = empty_forward_untouched()
+        then result
+
+    // g = (1, 2): grad_input = W^T g = (1 - 2, 2 + 0, 3 + 2) = (-1, 2, 5); grad_bias = g;
+    // grad_weights[1][2] = g1 * x2 = 6
+    test backward_basic_case
+        given gi0 = backward_at(1.0, 2.0, 0, 0)
+        when gi2 = backward_at(1.0, 2.0, 0, 2)
+        then gi0 == -1.0 and backward_at(1.0, 2.0, 0, 1) == 2.0 and gi2 == 5.0 and backward_at(1.0, 2.0, 2, 1) == 2.0 and backward_at(1.0, 2.0, 1, 5) == 6.0
+
+    // dL/dx1 by finite difference equals grad_input[1]
+    test backward_matches_finite_difference
+        given slope = (loss_at(1.0, 2.0 + 0.01, 3.0, 1.0, 2.0) - loss_at(1.0, 2.0 - 0.01, 3.0, 1.0, 2.0)) / 0.02
+        when result = backward_at(1.0, 2.0, 0, 1)
+        then @abs(result - slope) < 0.001
+
+    test backward_empty_gradient
+        given result = empty_backward_untouched()
+        then result
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.size() == config.input_size: the bounds the layer accepts
+    invariant dense_constraint_0
+        assert MIN_INPUT_SIZE >= 1 and MAX_INPUT_SIZE >= MIN_INPUT_SIZE
+
+    // output.size() == config.output_size: each output is one row of W x + b
+    invariant dense_constraint_1
+        assert valid_input() == 14.5
+
+    // weights.size() == input_size * output_size: the fixture holds 3 * 2 = 6 weights
+    invariant dense_constraint_2
+        assert cfg(ActivationType.None).input_size * cfg(ActivationType.None).output_size == 6
+
+    // bias.size() == output_size (if has_bias): the fixture carries a bias of 2
+    invariant dense_constraint_3
+        assert cfg(ActivationType.None).has_bias
+
+    // All inputs must be finite (no NaN/Inf): finite in, finite out
+    invariant dense_constraint_4
+        assert valid_input() == valid_input()
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/batch-normalisation/card.png b/apps/website/public/learn/batch-normalisation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..e63ac6cbbdbd38c3e841bf85920b8dc777333490 GIT binary patch literal 50254 zcmeGEWl&sC^fd}6AwhyeAUMH;yKC^^65J)YyAy&t1P>N8xCD2%!QI{6-EJqp=l_0w zZ`G~3&#ijSCz$G)IeohK+H0-7dxGU;#1P-&ynXTF1>$FMVTBhjUYEUi@yZGI6?mnU z_yGRJ3zQe1g+G09NjX@A)BLje1bs67Lu3RC;~nGIFHs^;ko;CO2Fi>dAFcfzSs@bY zG=GjTG>RL8YnbY*S6WymF!!_}Wv?VlzG=6$zmgCTfua_$#r_i2wfCH2uZwr3m;7?; z*6VJD!G5dgILS5roZEg#_ml9y%gD6s1M$DBqEkTp-%EzMSg^rCf3JaeP(-MIujnNG z52XJ_F)1SW{jYb1_(c61)hoq_g7$A%5+$_Ye;>x&^?yF>|EtgJ@?PL(JKg*3e=Dho z#bOe*GptJVe{cOKTj+y@{@W;8-EaT5*hQ1aP#JOOhj40edJ&dLa(IMW?$_I5Kb!h3 zoxV7HNi2*~XSGlhQSeDkcK7z9w|j1RdI&otYqid+nMNOt zb);Y|w|;G)*1#=Dt)q-YJ~u5-^o&To*6L3Xdwq9vlc&VG>Cee&ddk?pJ{~zy%~csU zFD>7n)$SRW5em=faBx;zOhy|}4evrrO$*U_*A0Eg7r#`tC%Sy0J+%evC@mxP>-f)N zm2`K*M>1+UId9gfciY((5#egh8J8H5*I~^}`mPSbze*?c{i=B=sJ&b#&W5k6n6?qo ztsGgpY<>8UvuhX;iHS3haCpd1R(ndE+q1H`ms||`S8;Yf@AuV+EEZxD344B4IG9Vt z*j8`s*Mn3|Yag;L^_g}?-HnSOCmi%YZ6))5Wu+D4_ZmV+9>%hL3aO*ZpDw|EvzloH6g| zR-SkZYH@QwPUNE9P09|VZ;xivj^2Q}=k8UNZC@bwPxcs`qb7zunHr)y*;L*T%b!<+ zLrt{oUflbq2eO2Xjf^#Mh@rHbo`+S<_|=ISibpO7bm@ATv=mJ1`uyAuPg<##473Rs z2f;r)>r9s|mNiBpT z>g{#6D4C@TJiI?x$HKaDvnpnINnKSMS-)D|P+FQbc_a}tAZGmshnL&veCwmmen3kx z{-USvq9>H+V#jyF`8i_9oGbs&C^X!IJY4ldbUajCyd7KuywlU>G;QuFv-GmOo3gT% z-m=~*+6Z`6&gFN>KTvj;IQ9iMchK>gIH?)fcxc@AqhHqK2L+kDz+yFpoU{ezJXKW1 z%-^6|BAf6&?KNNq$e10FYarmVn(pO&wu(uaYHHXVNkYnHGE5xL&c7M9deo4 zXknfCWdB$-gee$nL}qzBZ(8OkB+7ZO>75Wse(&p;zLj=h^s_t->yOQf=^ zy!mtz4;3=@>H+gPT{`6~p~VeL&3yTwo5zY4eChNd?pS91U@f)TSOnrR`7uB9H$lA? zWWTCS)BcW*wK%g#2rm;kGQxO%aNl!p% zd5r2(pv!5q;wd&@mwOXuc67xYT@KC$)ldl&E(G3=TSc6}Eq`O2<%IDQ>FE@`(?2-v z;v9sp%<|1L$YBZMjMOHm;S?+EMlVO@8$+v1xfEqp8*TO}v`fMa4(i?6lTG1ZZ`WHR z4Q%`RbsHMlIho~cTnxIeSfxV2rwKT?Xt&18oTPNGpVh~HRp((N8b&fWTP*AGNp<0@ z-CGhZZinG4VQxEE?1NSICFxxHu|`8xoG|?J*55hgyidkeroN^gbS>SktS%7|Dd6v! zY^ls6UnX<7G&dXbdSn_6S!RqG)gMNTWex6GumD%Q(DAS zwn%32N9HG)By6|-u+OR^^XfDvp>5m@E@8*Cb~rpgV`3XUtv`ofk}i*o1b7-)AH+Y6 zzvFW7**P|g+{pD_`at$ub%|xJy)w3Yd(1xhi%k)pX9pC1&e7dj(1}v|c0Ar}&E;ip z&?cu#mVs_<>0H5N{zR;Cj-?ge=C<0VnX@S#XEM5-8*y0v0@Na^Y3R7Z9|$9^1Q(vF z9Mq-K`tw}nPEc>v?!APBlQ$kdY87_BIf%9`gJ}nwB2+@kjrTnwq7oYUq}S`4sL^m; zE|5_bZ8hHfKct>QUkn|7DkouI=Q0~?6JX`VZ;=sk-CYhlC&V5|>fmCdrjoO=Ubj}O zBLL3Rm%^>3?l#wM8ghQpCe9o~&IQXe>UQjy7?T|1@6f%#PG~)Af3uOq{M9{%|MT50 zjW!OS*TcybHOw}H!(1S4GnL4-mtXSm&C6-eXaoYjH_`9QSA?C;*zfPZqE>EgWTd8h z{8|4qBorjuV zN&QdhYQ9jQ?3G2Xpznal`J!|6WYTVSTSv-bHW_bfOiHD_^=uzA1>+g=1{nqkc{m|o zluQLni=t?8v3UqQd_O$I9@!qSHj2U6Xvm;q;;$aab zU{$QSlOxZ4E*Fd_PaelZRl)c4SSYSOB9N;hGo6&sLEq%$>bvZ!ltw3Vq4 zER2&NLoTKrpt34Dp30ok&_pk(uI^4mX?JtEoWR^R#0V82T+MUp%)YECtg3o=qoP11jnzqc5$@5j8Kb=|k*k$DiSFXWXy0cPp#oS>#o08!JS1 zkI*?k&snQMib{W{7^sSX&G)+0@rxU`v%=eC8O)A=$kr8BsDmCQ{k-`qqC9gVOpDuG z{&aK=dk*L0QS2;HH3WMsHdTjpLkLkvfH*~{L=T<=38%fyw#vLLcW_KjF8$9{lis$N zS8o>evdVsaT{MaGE#4$6=6An(5Fa{_bYrJ;$8t)Hfy&QG*7{JiSfiJ=9AG5NwiStE zSyw$P8CQoJ&pTr1LhWed=fIT3MoW}aM$!H)ZcdCY4P$%b-BxV^ybdeGU~gve9$I#`sI&C3lpCaQ<_Sm6|sFGt3!6o zO$i$=I1AYpZd$5f4ZJ2LTq3!Py>lC--5yHgaZ~3&#AP%MiMh<^J{OYr%-ZmGfDH&<0nBR8#9v%s&Ow3>j_h|xDQ}}9YD!s-?(?4fEtvq!Y!`vfG z@TGTUYs5D>NXGmIx#2dvlAyM8V_*b33k3$5+&hjoe9&!e5LxUl-0U3bO)5Kp<3s16 zShE@{^uX!PlK#EadF&4eZZJz|OrP({O-zs4UON6UK!=EY70iKuk;)spIQ1PV$!)vh zxl!>s>CTg|<&TwY=-ZQ|$8@WkiMu6@+)Rl)xGwKYG4Hvgl!ZH9+B?_n-yf{pc{*ONZp;1!5-n~M z$z$5EzDmupiu)fekV78_&k`E*^?tG?=F-$%?n%?2GAvfdEiFY>m>TbgHulED&To3o zn`1XO9|?B@UX`Op<8nQWrXATaaVD?3e?*orrjoeMq96K99S@Oa^;hHEY+oE*obDN= znkH4tBBf>Hqh^>>QBq7qX_&PrNm7Wxc#n!Yc}0t4E;%;M$6$X5rJU8|+mV%-Aa=tA zE!NYu@w(a;8DYukdr**+(aB0%X0F9{vh1P7jr%|=qF&fNT-49t|2oHZ7|Fly8}H2ysLBDc&gJB2b_ zRHGxBLF{7Kx5y>gk8RFVvAM=AXR?!=m+V-a*3*2>vlN(-{G66T*VrZ5(ck%>qK-Xw zaeIiZZyK7}p}B3HWv=WH&@3AW;zuhGWL!61Fbhrw{7Czpn(9F6nY4WJRlim7NJ#bQ z$wWfE=nE+w9Uc3J=1GFS$A`<_cATD~THUxg_8GCua#J>RR8;wS8sTwxKcwoYq4)0$ z6T1sb(-vxKROnNJ-%ixOuMjTXF+AGsi6tw><~uCOn_tXcyV+g3NirPl6RPVI8%A=! z(H;yU8dB^=UbMGsEz-0{^i#HS?y`)4w~zJW#6l%79q}B(rKiXm3|ZEk5%MSG-le-J zZYEwVT(a7aezF;M?WjDnHDl%az{It%SkFPrR;^|#!(LfMWKbZV_GgN4rhau8$MT+V zqpB{?SM-f&o@Z9(cXajmdpXpLOQk|Hi2Wa@eXmJ1jg)FmNnE@l1srolqXN*B_X%4D2}*p@8PoN`!7{Y zt^Xdpa1!(yg3K)!>szwp4AjNA*KDWQoa3%~Tq4w@$kuyCMzwYHggIl8%c$T@HE<0k zb#MmCn2RD*5U?Ti*|(;!n#HSNSJ^f2TG@Nl;>^;KQSs>e>ixcC)t2dQ?GK%EU2Zd)1j3W596Ce;q1}ZKp zCMKqZo^sQp!bvLj7xHx^A*@K@b}8!3oO-Tx)z!DXxX{s*!{ga>LzlR|t4kM4sR%I7~4?jK`{BF+O z+Az%@;~D7NeK;lzl&QbFOJX(}nBZ_cpF>|XXJ8GiaEjO65_N&O3){6CH9xVb(ZF1C zx87(XQViJR zMMrP8iHV9!h);lrhlxQ*cxXP|Ef>LO*FB1vi?OF5Nh=}m&#Hg|=irRT5L{NxL0ydU ztn#M2vxoMrjlEOz*;V4r48twLLhRt+aO>n&_J(-ADn9o6nhSDkW8>rbgr1(y*xKSG z1s05FgPg2mz2Jo<$DDbSnr|ZIwqub(@sEzGej?%kd~~2imPG4Ud4&2}ONN(@o2t zoNC%qsQW+9yQ`ZGeMCdTShPDb4CbNl@URMPT;JLM_ zKZ^DK_;K-$u2_z~@&oGDyAT1w-6ub3?{uS04;4WfkHozP<|BF2xsSV_Ts;zp7t^m- zm;Wejb@q_@QTP=WdlIjW5jzY|1FhLpExuVrMp=H!**3~IWwz^mdT3;4rfuJpI;A`GN0)tc?kU?5Pmld7y|pc_E@fCW47`9i zS>c1NAk|UB3rp>!>bQBC4};xr?s%g3Y=)r7i8G&$7W&ei47Co~3}XFbmJgBdQ@vLm zhOVkhbJrXm4d}H>pF2knXqWNKW_9>gqGKKgD@CTck&{@~hkA^5()b&WldZ3+Q`rJd zk32t(AJmO=9ydR%J}DD_qOM78eK>F-aq8Do{(z|W&tTbg3Jn*%5o!KV};P4~FkNfJ-!qH2;?xDbBQ=51j@`q14 z&A~cvzD%Ak-1Z2Ki?7#YEdzEgYd5Eo-YCxDI#Q;OGkcui&XdxOpO1TWF%t>q6lzF|_7-7c>mh1Y8`0Ut7Awtm$6{D^mD(Cb_6M51i+SxnRGHbu5 z#-OtlzeI-RvT1wlqoANXZ|(|y&ZBTyX5_RHUi)emirqzazCP9i;*j5x6)|gTe6#a+ z$N6SRzl+`1eFuDh~%RlT2cRdDE`T>PA$Qy7CE7&K{x9E=b$&l{_kak z7c9fH^FKc*qWovixBvR&E9^bhvYqzNxDToi`yKYb*A4%lnga3v6Qz@U_)Y;`$IY>U z3U9$#clL11iSdI*Ywvp)*Ef=0s;)U&4Za$6gI*Vh8-!kbluer!YHe57@k<+)6nEc8 zRhBNVuD&xZ{t;&m+AK#~G(J(7f77USVtmh~+4axT=hfGJEx5<)wB+2B8Xt$UYhXFD z0_a&&LQD)AF7`o|@@MOECkN!PpxKnT%TX;W-spyUJ%?6vO4HM5pQDHX+R)XzGX+2s zQBkYHe}^f|qd*(1uM=<3s4Au?9_*|ydBy%|u;UC+fi9pNlIW*=AHnC-Y-X-^NI-y_ zpoDdGcO;>Qqdepzzba7#Qf>CeJ9G1mZS%K^5Rn=O$NVbJWOn1Y=@jpFb$mS3qHb}s zN>*0DzX4WEGomOYi^7P~s*LHLZuOq*tOdosb9TJ94nnw&8#hpvvYGjFK{6JjoMjy% zJ&(6b_r+zB!ppfnA1y=TFz?5cP8td}+wnTusA7HNL>Fa0Ny6q-8sVt)@f$Jm^}g8@ z1y$;Qq2-pUmd<3hiB~56G?{QwQ5^G?pS0zAN7~Br*{Of%{wgm0D`sq}#lxGq*+1#b z{O*TWY~BRMtXwOj*VWG_6-N~2#r6jW=N5b9z50zNx*}M3G~7wa=-8y`T=G2^ z@ZC3FOHi9?cvL<<5PM(EX{kgU=}v@q4gUN|K-+RTp`gJ@z4<9aI&^t}=U**QRIeIC zka{~=A8jqmLn&M~56|;EiN0?K$vR0pG5^wZqmb2R(?=p&I@O%#l&Y*bb{Z<85ixwc z>Vn(PKFV3f{baXvoNuwtXkoC8Dd@()|J z436u|W5j_Xw*mfQ!hwOsX7wYmGtu&TN08w=92pnKi|{a4ZdG=AR)4s1+g&m(8QoOv zJ;((N4>a$H2aEEN9%`FH8I7!@IHeK6zXDel!?=LSCME&y@9eg-B0oRBO1umt;Y`>s z8VzEdT}BuI#eHBR&8g&Pn8Jrv zErxSBy&OF)m%u5a9PWcqO%+V=HS?(!M))w=GIIJzD;HLAaWGMhHSHeM!ieqgD#m0< z3w(H|HOVY#xs6Uhl!taOKzKP6O1e!HiJ@>~76NK-V*M)p7{qQ> zbl~dl$oQ$_8qW6X&IaY%R&isI?t5_8)~rH85JWLY&5B2prjNTxkZSu^=_trGRSNGp zi1_%3sqpek$$yKg?zRZAOR}ml`n2`qkVn)TN~ml8Du`1Xi>ctDsm&0?PLGO~;7}EfH6E+M|>DTf203RYP5= zxgO6Ca*lTSV)vqceWCsxh^C8LV*d~;fN6LcB{P?F+4UDWOb(xxOCIfzgm{b>rE&3< ztqSY?q)LaYxAbswY^V@&>z_z_4a2Ibp~xcMAI(ll7Xdv}xrF(ap7CgCb`I+Wv{I72 zqt%R(;o~6SGu_23KdTGID-&d7*+IQVuV`RmVpA?D*6&+uNOdg2n>>ObU!kN7Z8wvs z%|wksy;GXJlhjIjO6>XIUuEqO-zXh|nh2B1zA^T-!JSLM$u7S*1&XA7Vbe9pvGaet zfDHB?aWSQCBOB-Iq4&?>E2rBT!teNgYUO9#_y8`9{RjRZk}4LI49( zM>X+w)I4&DU}fRRU&Ab`RelG>uuM|K?yi zV2$+yviSVmJj6USBhx*L_-}a4#jaaz9^Mn+VdE{W{h*JlGvB_=?hNqv59~XRlF*>4 zvbOQFwsEPoRy{G$fH|}7IwXV|y0 z`pAAi$6S(^i-CAR%uQ}#LnZp(!|&FO_bICuE&TFADS~RBZuw)A-ST!JapqcRPEQ0M z-yV{fpF=GXlYX7YSM<1s(#WSph+~D};ZEMO#wY5yERSOBFSJ#j+rNDd_a<3Xvn=y= z3VuE*kIcyzYsivwCRBz>(rU?w*7+N*ZnesgOn`ke8%ukZJ|n5b(S zmilQve!N+&$ayL4y~%!;J6-+!?LE_SL!qmlYy{ENR6%YW5BISMVPBSnHa0{3?Z_Yj zYZ94xdYLZaVrTIJR7ac!I_CB}v-?lC;?1TW^i$C0{h{zV@NI8C}-I^x&jM6{Pmd~)4$kYf;wRLqXMPA8sB7!??2aKYiEWpWnLB2N(D<&UL)E& zAjtMA1b(gwr!OhLLJST0acrxSqNF-gXWxx1BxKGSn05g`U109kI)yle#$4uhOjIi#!b!#yr;772o=E zG4K#Cs5CE#OQgV^eUH=Vu*Cd2WyV<#n}HM&q11Oduthxup(SQxlfo{jmD@*0J$Dk0 zVKlQ}GnhU)k|8<}$N8b?QW;sr#ltsEK0we zLQGBM@A|I|C(QcW8$t8yl_2F3bajhV%;#IaCIZ*PX1_df!k!x-QM0UFVy$m(6U^+^ zGUI=<>^Dtsk<&yX$_9%jn)5YAl^|iGPd_-ckWe!AqrY13m>lB~>3%K7=32!-M4q9x z^~LBjKH+AT!mXc3S3qidR{KqFo(sBWY!~2I*cka%Pb^0C?P9Jo9$kBne`F;pdXTkgf3F>{!B$%!GJ_L_+}aIC~!41(7ZuIdgOc8Z$$zY8UK=O~D!_;`Q--`*7Y z+j-RcZs01DsfsL}9}`r@u@inM(mZpNifW|9puNZ5Il6D%E`FC3kxdUTDib=NlH>hG z!P0hWE74}TOnC?ulw*k6r`d_wh-k%*1#>|chUuxik56>5l+aHyo%EHDi!`SF_6loR z?H(TUwcX)K1p`{RN9*VWF;Te|AvmVgouayv#S+J|E$#MK;jzb}{}bMQ2x$KTP1rDg z;DOKYzrVLa|4$dx|G$dmJ!~eQ(ZkKDH_l4ed!2Xx9^eEbRDocv-6mvb$7Ix!LMG*7 z%;VL(HUHzqcp#yds=7MWKRz7Bh> zF1xIU6A1;t{_A(j^osB)v!`o3X%8fD+li6oL;Y`^AMv2{R2INUS)NnB|MdReFcxgX z4wy;fS_t*)e_try(j_n>GBq_d%yS<0zed%7QFNrFhHIU{|1=0NEO6x5bJ^tt1qEGQ zT`MSH5OG+{Ch`~!x?e*>zwOX;S@oBUr*XYm4g7Bw^8AJoJ|~OL%hJ-)mitO7D$`1Z z%8MT7gY7RGY5(i2y42aif}M9>Y4y>ts@pst=0`?EJhWMXLnr?`E3?6L?VLoM!?28VH($e8^aZ2~TY8o2coSbp-@qatM%raW8V}gR_*k43=oMtjvayjfo z5&7m%n*G-=IDuR)IFsuOgY4$w;=nNzj85@);*OnjbM+-95!=yd^4{#Nd_CZ1SnM{$ zg`lY^DN$3w2rxMWF|nS}EHUs^;n>Vu6ZwkbaXk_E{k^>|&yUyMH>)tCN~KL#>irZw z;kXnCCx1n2?S+)f8g*Gv0rYfRu#p^}K|zQo7FJGqP$>0nY;Rz6y4 zx?hjvmywi2Z_>Rwm`zJd`#2Lp$WJg|QdD$svf44jRaaLBJ_7|1C@x=U#Gjn@xuRL0 z#l;24!9ILM&s;ffdG@-y*qxhGXOv?=sWyegQsN_3ct1Z?7!SXN`hdgxaMB^}8$>;* zT`wL$>T3-llZ=13S&x+EyWM!NDf=A%2Dg2R z_h!YnR|OyGYLI;y7K#T1QJymI{XqroxUOV^rd?k=tp?xy0W*|jY_5O3{-;lEQ^gwd z627!VcYK!gJ}a(S+OtWFimL{%*A3KB?B0#t-Q9pr zJ7VHJHB3y*mglF255#-V(0!c(Z2~T7p`ns;awFa0xYq}>zJfM^9oBP|aGUu~&;ql2 z4adzwh|&lgDq4<8R#r#f-@prBOQmq2Doue!gEct4z7`|LV>OEf^BA|av#VeE4u5cP zaI)!sST)V&?%3`JcjxSd!)zqgpB1=h+l8TWb9)xBdz zFV{Y@grJu&%L_W*k5xNFd8y5JdxhRlx5kAkox6xPMvq`+pkBSYQN$!BjuCkO+y+B9 z(BFT4dHJ{+NNBV1Zt=0RvlC#$8^-nfwOv>L9Cmm|9UKE6f)1r)BUjycp_MN2GX(>~35d)TF2}uCN=1gW{n8c!oqbhW2!102 z+5mxeyM?a$&G|Bj`HS6gTRE4(pR9j_V`>sSmhX;hdwU_Kdj0xa>uYNzbz3+rVJRso z5Qv1K%790t!)j0-wlZwPE5ce1f<#rvTTx-QO^VIGxVWe9(16}=zV|4zVY_4znX~e_WqtE zdvIT{KKi!Z(k34oll@im@X*Xgi&Xya%=ue()_A|mgRv6gX+xJ5tORn3g zV0YlMvR@#cIJvvu_Yk-vFd7{%H4%E<5XGY&3w{v3MUqFPe4oR>qx#1%xTGv#BVfRn zQCD}O4T+Gih{yYAfzwZvlx5&WE}z@Qj&Zu@)Z*gfymd>{VfB2h#0TXq0MdbdM1=Yw zLWYT$Q&4C)nU^3vL}Q`0mQ7$_VAM$O0hlhjGVgQOM?aavn$50C)%+mR6KTT+g?NX1%UvjT7w+zjV4}yS+BG;3)E@q5MwF1(&EqgBtKocmf^^ zmK$+dfryCc#>mVV3lI8|{txp1cmW;J%#155P&i+Qk5aJ5(3)G@+uOr*ib8{e7&ba} z0azmDt!F6sdCT7j)(h}`vPGCI-rL)Qr*A~jsrtyZo6Z`ty}!RNpAUL8J5O9n&)}Ur zJU`qMS$~jUQN#~^wfb6C{{>!+$mU5fMVegqH-Vs?%!gRiECq5u?A9-GZ-q8YoMvrE zl?g;}m1>DlBcraW$PPQVYt@(;(K~qvwc+?++RYauwh!O3*{A*DEs-&rs==g9t&o zGAWq@dPAJ`(omfl(FTH#v{dD(;@*zpkVzx>vihF>`W74)kibB?6ydB#F8{7e(s(Fk zv}JF8cl@`OVInpSjXp&?0UKVy&zAmJSCq599GBgj({-0`KGAmNax+}wEvh-HO*2z7 z7l|n3;g){Uy1Hb<`YuxMNS5mzsfYK8_Q;^Nr=!aL7duTxLr1qwDSDjyU}$VCo6IJS z<^NkHM)WE&=TftURW?^WmfZ%;AnJ(0%;i}(#&qhf@Q0BFd7 z2krcey42${(bx*^M!bgACp0;2K??z%))&2KLBu!c$R`K^JqfS=yiOZM3_D>~4WP-; zTtL2Ld^bB)q7};YPJy^UDF{8tzn2yQmyQK}`*M=)A-`WM5v4mUfq@_lJ(7{OQL?v+ z10gtizxfBli=~L|I9saEXmv8)e&6&M(p^aQ47LripkoAv+7jb5;`QoIcra1u^&TLt zSjAQ^PaA*qM0uao%H$^d+4;CPhB#BI!ACNBRLr)LGH6LjVnZvo&G@DC#KO41=SH+S z91GSd^~I}VVEwkzJDm)}2(_s8dUR`)?CXFyT-MMpMfkV-#r_J)H{gM=DQxK^l|*?H zd{1D2mXdV+Jo`&k(gm7Y0vkC%rDQkKr`+L21Swi*=YDQ+SJ@gGh)UX1>)@0?Vay0((KFqn+GKjX6;C}(eSS@2WcAaZ{SG~~Fcj9$kJ#p) zUEM1r%Z|zKF_*eQ* zaoLu~D~+({ACh#p+x*X_y%_cW9(M2nUrKyLg@v28L535yz~yqtD~S>jp772{`Slz# z_XOlqXi4K41gJBG=bqWOom5ctO5fKK?GQJOhO>+=x003{Mn*=-1UhM1+2ec`)h}QCq|3aYy*6cq*V@|!vjfR?H`dH4Aowjc(=`l4v3GZOSO0`|JZieujvY-&O%)+z z_zHO^1kDXr^)EquV&F}LmN&K7-y*!dz5Oc&hI z5VKBZW@h&tMXKem>g1i_Q=NVZ-u&e@t{!b~-p|a=I^M+FZx3~Kb~xO`1q;S zR0O^C?(j@&8%IZ0z#~-kgn@Q9*`5T_@V|pYX78c&lI1%42L=vo%7DBc_{l2iYOxZW z3$5Mtda|0&j?z--)#~YbPq-Sv!H7Wp#lLc(JpC$i-rPB0mSDP$95Xoy+IO1?I&W{& z(A!@CxriRX>3Wtek%N}YW;Bq96!_`GUmKwqo5$q@&}DXy{J7ZIJVOpYx0{nyL|nEM zZfB%Gd=e6pQw0Tuu~7Qv8?c&-UiXK;Wz&a-hLDhu{z@-QTJ=ijV{HTrYisX|9r>>* z9f8Q+XMGfmWp>n|fTMZsP2}UUTZM&$0McDrQol#V!*4S30R|?}^Zp7*GBOGZ19h<9 z?F0qeL4L7aI05maQUZF&QGLpr0Ih=HPXcmo)p*(scovSgHqcgo$#W1Y$=TVNho`6W z!3=ONe4?`gzrAGW05+tH9dHY@wYBGKtdZg2?|~swV>ur{=C+;cjD*MWp?7D55Rk0< z7UMKmaxN|$nCt7~W$$^*8a;cSlUAq(=VKsyFRrhj!Sd(e{hBsmG10|Z>gvkL&4q^I z2LjT>5vW19IpjGF5s^3Q^7{J3(A|<851v3e&sG?}$HdH>1=b7LZO=_$ua_5(y1kL- z?|iH0ev)L>t6SgrMOoRX_vA(!HK6WhEmVZ?TVy*@AU3C6Hc(V%h(A=VtmxJhJw2Pw z4DLZRvXYQM4O2t?Vh+FX_buD;&WZ^qxQgU|+F4!o(Y~>6c{H-L47Xy3R(w*@bejDN z8=oZ_uJ9zRKVeoCLm}Hu8hfhi2V#!9{)WRapWE_v(=8yrm6a^QpR$EFKabW>G?nO=cDWxUX7<(zI8CYwG!EgH-x0}6zM zgm?k(JX^sg8Czu#uM1e%@&U&y(f1r-C3m8;w4L`RC_4q;EyPOlX7Pu=MQA=d*|@vh z4@ATbXl4yz$g5ZcGSjRIr>g@bF^6XPflqxh*m}y!m<7CfTvXnfLXkw4mXJN_l|0HzyRq!g zU@&JU4OJ9u<_@WD1_Ko6vJ)^9Nky>_qF{`<$rNLm9HhdYohdhvKW#W^haW{4SsFQ! zvk|QnYWT@!iGxG5#-$$0#Gu_Z)#)URD-Lz~eMY zfcJ^TkO7Zof>#*{rwX|TpS#hI5=m3!Z_;Xuav|T4tiU-l7y9QG?vc32C$S+C@_7Jb zCjdcBQ?tlDOkihscXm}nuI~Y$h10>z=+uis<>Ei(<*1$=z;8)+KdM855yJ5RwwL3y zrsbqBGM@{8D*#S{piigD$5BK9Yy0P_g>^Q=y!iw(@S+~?E`eTVHSEpIBwkz}7#J`w zsq2n%_PpIp`0FM~NJvy{1Na5$th=zJUg82%=;e>UcAq=|9;LbMQ3@?_Sj?1dY#2^J`1^%(9zINDE9q?g|m@O zZ9t#2ly5e2G0--G&f)0O-LF2ip&7?F{Yp-NvB z0P_o(ikjNdJ3cn{!tgJH z((|?jq(K(=)PQ!O@xD$v0gM2d8Q8Iuu}Jkh?nOmKKz2#ZaDS08@8p3UXFQY;=xD{+ znH88}kL1%Wp`oQUH#3u(St=`*C){ruci{Gm`$imoBpTiQ8;_EqP@uOk%&8w7!)^9{ zeln8vx)>D$u#O2eq$ta)q^wNt7V!hlx^@*B*s>E88O~n7{8(L%rw=FKRev@LI270( z1Hu>F?$I2gds9=B2Cp+*)}#qbI|Ef5)yI!{=BT|>Q%-Z0rVwe8*oHe&Ap_Qg%d>bt;I{6let)E5V0bv4(|!xU z &V(jG{%%*@QumU1k>TzZRu03IeSJ-yf-*k@P-x-S|%=c_GyA_?E0St}eI9!BDE zGJS=_^15F+m=Tc6qy%{#0*5s)a}b<%)zH-RI9d5bT3Ap(C1nEAUm}cfmEvz1BD~z3 z94-4nR-h=`98SBTV31Z|s}y!d%&K-avzQlW3B^{EaRRN%H33UE5Et(Sx!i^Yk7#y$ z{2U0}_B#-oIw1CaE`42vreUL@vNfUQ~D>%|CpV>Jlz)k=0 zV=G!lRo1Mo&JCdMN%n0y!a_Gc;EDj-4hs@K*1A z2JM<+ZDwZXq)It65GSE8ji*brfQ=?FJT;<5K}ww247cnIXpWc;Ix76*my03Pz!8xr^5hIS3APqgn)f9vnY1cCvx@O%$O|P*S`0 zHv2ogAr>bR*I(tbbDFjN*hA>OQ(uO419)HS21Ct`lyi%YhN7ZxV_>=7t{ke!HZF;Z z@~blfuKk_Zb=gIUR$)e{#Bxvp7%21NMJa#jd52CR18asTh(Bd4ArTT2gFeOloyE*k zHO7Q9h>Iikn-Bsd3SuPED~9~G4WSR_P_Cxn^hF?4y>fi3!)O^Qw{7f8Y4}6DdDKO% z0k||VNxAmMk|sTvHs$Vev`SH^{lLSHoAPX|VmsBBf$C)+IHtaJU?;wwBSMP!C`5IL zXb$}u3l5vR3s5pgM1pYi285*<+yoLF7f?}pg?I$&3+=W)fzbzSWykwN0W?Cw=fD0s zfq!JOhINw?!1l|}c?GKi3~xcz>x#)ibky|f^z>7-Fy|+kULO=FU2%t8dCt)${NXH> za6R>>fliwpvaI=VYbhyI=5H{NQ?)NNqo$&+D33-wzDM+DL~dh1;$SH_BfM8b63Wya z+YAaa3<~-#7kEm2iZbZU$=p_C?OyZPyJFvP>ZTN{iZ~va1vVk*HB8v z(e~P!zOga8VK2%C@k1zP&}BdfHkCo%BIUJ+Vy29?Ho+Ve^wgx+=s+3m$VUAGw}8|e zlAbSRlTk9!(5Os|Y+;y@qhoTko$*R@xa5Aqdj|(a_es<^q5=Y~8+|c|jouoCW!`$T zwy@AK9WAPGf_(1S_o%r+IIMf|f>!Z2??0iQ2P!mmCnq}0E?Cd*wqfh z0B@rfF2=zLNpN8!Lh1F$Aud;2Y8V=lLawcwZ*zA@-~IXS>kH7D`;sp99;9oMyD|_V zfK%yJZES6Y3<=fo)6or$kH^&frufTXm@u@zR$>5BI}ebcZ zB{qZZFfjtx4SMfe$$O~3kp*gWbAXzX5EBc_{x$VJm3FjU9nMp5Sr>zf!~WmI3>1$> z6P**Ysz59zurt0E8UI&2%8Pox>FByM|8gPxt=83! zKz>l~!k5_xq)|pj#%g~OJT*GaS~&+ppjY`HPJBNQXKIfSdJA!=lDnnb9UsTPKdP>( z>bm~0l~Lmz=a--UqbdbPYO%GU$uY)G2@NU`&!vS3kI4|W{ySvTRoJ?{nvRxMM7C)5 zdp5RStNfwd%{MI;MhHXdSe*RFH+4-XGVRer@a4?X2FaLDfW?*~&RsP9xh2&d0L zAa5)5Dw`Jp(UPZ7eCnJ4(++jfO<^G4K=ebp10}bD{ahWu#v~M&wj>0$8#+`uT3-?6 zmW-M#EG&e%B1**)HUnG6!fI32*m%32zC|-f0nVT;fR2V{ps!D!4l#rmNy!gD-b^AQ zLEXFaZ-z5Z(i1N7*ngM%{JR$?g!N`R5uf|Q7xh&%Vl1`*jAv&Ms^~r*{H@?7D9Z_j z_W}fD=kE^d%sdr%@#oX<(q?U>5RQYhGy54ns!dVb@-ktv>h;XfkPKGzj~8+CF|A({ zwAg?*K*H`qa|Q~#aj6jw|9(QIcY!D-aRZB=ydVWXgri_#Ob!d5s|Vtl9cGheR_H+e zDKQWfFNqOxm|-c)0xT^o=$bARhyoc&h1N^$X{rJPVc6KIVt^WC>J#mW*xJ}26-WN} zi!@2x=((t5SRdk&_K@aOowWSr5`!3J6@E01X9>36K z_EV}X;1n26NhOQMe#X7Em^6|~lpTn&Em5Dq^z&w68@ICE95B@5@?5=B@_hUM!tdT_ zefZm&kS7VsM{A((^lx!4u^m+XABVV)!|=H=Bk3Cs{!DATAO0nrAq1`d?g2>nA^fQ+DIkoaL41U!1u*ghs(ijZ zOvqFFnap&fHyWA$!RE`C39xpj+dvGUU}CblUs;Tfm!W}rU@p*x*x`+{k|2QGfwlyp z&oBTeSUO<-MJNNozlK)sz~0Jy`9@2~0Z&U)Q{7W3M*$T1yFqd4!mqx*ezCzh5)jiw zL0j9?zv}rbHj`oR4>C!>1&#dzj3oFQ5quEc%r#51R zw0;j@ZKrZ~%S`8>HfTtYb91``IH0Me#Yp7s?G3`fD5+R1h1VVPoB?zPfF=i4cRmu5 zbx_Eh1}6udxDIS*j?27*wSlhqglAG#RW<32CK-;PDKBpedJMEdg?Dvz6`)ZHhwU2R zZFG6eE|8A^V=pNHMv1=Y9~=}}eU&-^uw3|7hh)uGULMsg z1hjqpZCe4BmVXMy-yGN&Vs!z$2H_ffUN;utG6K5Y{;mvmTFV)q0QhkkQhqbvdUjBb z=WApy_~79~=dBtLW4hNN5Xc~ay!mRxI6TI09|EM)`I;IVA6k8&aKfPvVfHac;dkF7 zBGaCL<(i$HRrNp!{^oZTAYN_IgTx}gZThkL0AHy5(%U}WUOH>w?mM+)XQ$(=3xVW(3B2d3n6vGqY z?ra5s4WJWB-G2uzA|hg@I5zGCRAlv!yI-;WU%dTQTvmJc#tREbw@9~0gGh>mG)hQ! zN`o}g2q-Nn(jwB`EsY={4bljRh;&Fdd)(`J|Htn>+9&H^eNb-aJ?C$Xab4eQOiDCi zVF3v_x$j`QR6dO%;|Ar5DEUk-j%n#(6kTAYBmyMA!ffZyuB@q ziiH@&yL!FSx}qX^GVJ|!TAqPhe{ZvY)hNzNf&;wO}D2Wz4;D0bEw){il4tUU#P zzhTJ|Rv=2Ss^N=YcV(1VL5hCvTKDq&DT5+uDTQNCxTcY0f+D7&=Q?79`%QosMn`@x z*~A6ZaM7^}H+>TP_(HQ9`7=UXqsMZZ?|KksT%I>b*2(`9% z*&1C|dbki;k$Zt*#z4S=NS|O=SJxT?+pY}$9Z}EAheX^EHt9XIU&gls4-XG7cAD_9qh|{rVjZ>-qPhB;W{Uu{qC-3^dO|gc`MYuL z#%T>{8-0bR#Qtvfi07WTjicuq25cS08g3i`_br|HQI!&5ul@U`4g1GcRXjCnB87Kx za9ySIL}bq!Vf^P_C+D^NC8yC|k-*Et(+bKUbf$B2b7qYNAuFq^3=9Y;i6zgi&BQG8 zeU+>Kz29hPXr_AAmV@WNBeKhuN*ccIv^3qQGGecchxODwcKML-`g|uJzAf zpAk?u9WS#-8lM>wb%!)clb-+f#Kuxtv)}AX4ymrJRFzj=yKRP6Qd(MR;K?CWn3aWG ziS9U+klA=ERrxF}wMsfok2u-OyvThaAPGloWsJa@CWKEZmm@D8Js~lWEV4F8Z2sp@ zCmp07ioHlRsZNxV+s&x>uKfYttZ0)lJ#kFWUmo2Zaktc*>C-{!QqtHw!gh zh?yZm2$}PCgT@x-%L_PCoUJPg3asIT1Fcga8XIea9}2KHSV@Tb1N2>nW2jk~u*Xj1 zyLan*bHQPee?3y(t4jkAGpPcdtIu#L-jC`8_JMcY#Q}paOpb2&wo_b=c(^MvIM+$! zPsD9BSa3`?*_GM&rLIg|8{ZG7+9U?KG1xV9G>MgJ@ki*anscU;inhF3w-un5cAjru zKSsXl8E1ty%9k+u5yQn`x|s3F03#38n3SMy>uaz62Y7DAzyd+%Sl*=f3(5zd-^PFQ^A0&VYr(1kAV%;EZ{xoLwZ68Q>mmH0YFjtr z2R(g!PI@1j3(gz%&pLx7cl-8j1iY7p6!i9ef#bi!L%u)qBQ!KL0p8JX^M4t6ujd9l zQqtf0KP>-o1OLZQ$Gmy4v{G+4#5yEp0j+w-PGK z2)qvtQ2-gw8XJYKR+ZC)YF~T}=!zi4{_i4%YLhc=WWPs)y88iSP{Y^%y4Vsn5Gd2- zzJiQQaK=K->ob>ltcjQWT0Zvn+t6r3fc-VpqyK(80jw}QvT5tRO|Gh`IboDSckf^? zUokn1XC2BtH9i_H#eKykcpwSPIr2n%!_3mG?egY-C!@nIG!vntqoaVsy?9mlAUqyS zI6?AL&1GeH^R6aXI>#SBQkabCSkEdtm?IRayaSj^Or=ttXhz0id(>OA@(x$UCd_lX zSLFoWK)jrv3keIy(2DuNlms^J`PphZKv;+HWmuV;hkbsv9QA0ysS_7wH5%a8py6w2 zxdQ1anp#+k9y~*9UELW_JuYE{QaW&mjC%;SZ*#IV zi?YJ?>({Sv8g=M(v2{84t0XdR?rlShlGfDJRP`8)mc3Zjd+dPpgP16d4|F!T*=QuR z`nT1g7~lwq<^^*GY+r*SgkM3s-q6^%0AwyqLf`(bZx@Qt@TbSwYK1|gnFiTEJa43XnXZdVKO z(o%ZELAJJykheR+Dn4`DtTfRW_ngXC)z%Vs2k)A?KHhV*uwZQU-J>?YJa#`nw2^W+ zwbN33Whv?S1w6V%K$7s#v9Yk^pFgJtepK}2C$Gnj!R?N^5NRKo8#kyt#)X;az9KZq@Vprkkt=x z8g~e^)e#RQj4$DlleL!kW#``uUp?XG214&@Pc|8iO{BF#AZ~eEdr>-j2=h2=N(4H8 zP(SNsv$@S*1QAi)ZI>4?A37p8=>m=TIBk9D6feL59XmHSw@_(>c)#wmfc-4gpI|~0 z{pI%b2iQwZzu=zhMlv;#1~b^_c6k-(fJdsHk}P{cAtX;dqp2>HPW^C#n~)WifvCWXsv)f~n&5LIOeQsZF73M{>LAmAd;543&KMrlXfY67}ffIX*o%2%h4J7Ah3slLE9new&)6}$aCz0`YgA*wr1 z$Bkb9lgUZjq5UiUcc#VXgh*NBZSVa^Y#G(p;$(t*P>5t!TL9_>Z(+OQ%P5JJmDPB; ziuTsSh-k`3J3o}g`1d}2e`^9Q{=8hEP=WY8VnnL|a{#9?e<$%==98ui4>nvjrwWp| zZiy8@8!+xwzcpfQ-HCdIOevJN_Bku0{N_HM6nHI&QJW0){I{U=+*Uj7KJ;N$r=Pfo z6`o{~Y_F|_;p;EgJo-}!C1m5q5b{DzY9&6{BSZaL4(g0L_QsWEIUCg9%9mD3IbxI$`eVYuA&CzY-7yE+dFx;=W) z_z8^|rs3q_<7Jj7=Bn#F#Un1eEhh+OIV<$bmoIcg-rn83WtxOo9XwqyhT5sdN!#-2@P$JPfwN4rJoJJ80$P_F!I2pYC{f&2 zJcl6+Owfma%SkR!%c7OU7khhp^3#x161gw6g+lZjTvn((e$q!~RaERDdYY@-8$k$o zNBBRizQudu{gXAQ&ZMGP>Ej@!I3DMamrdj0zL{@hJd8m!)!6rVU$FA}aY%R=tkW`3 zLVM@2aWXB6?CX3OLr5IoBip)@i%i6SHvBYd07Gof7L)Z^t{Uq$?hFn(Lu7hHMP`E3 znYEqZ9h0DRyt<$TGg7}Lu?oP+koD}rDAzB4pi^D-7r3#sCwz6;F4%ut#; z(kN+iJC8F}{2qiYG{lyl6a-pmV?D*N%+teU`c(5zw_mZU`BX`DpKLZ&&QhGUD|;|o z#5#zbxfV;^ar5PzB}4#Ty%*JMLGHtS^m7l2;PFCPFn%)13 zu^xg;sd%Jo#wO~Qn+RhemtIZ5Oq}Hx)44|v-EZ81(-94@7Vo^aomKCBh*B^|w*9Rk zQC)lIsg=X3{l{>d{>(mm8O4d|pq~R3XpzP^Q&vTRT)reICaW2(i~BCw)8z|r#w{$g zfJl7ZP3ahBR1JNhpZ5{QT}=Ij7J|_hTMvV^Dd6UCsP@4*K=^oYxCnPPLtlazy{ef9 zUv<@)z1X_mhQX)*^78UF;SnBVNQy`-77xC!iGJ#98pvE&ei0HHTwH9M;f2a#jL5Ed zF9H&VNF0q~L%#y>k<3kynISa#gP%V=a{T;|7eJ26%+9Ys;NK{w3Aus%3gQcJt>iBM zes@7>wHBC$2+!h1sr-ObSDoXnt?Q640OTWv3S4PRk2%aPknzAqYqFoKLjWm|Ba!LW zuQUyQyRw|vRiGrpI&O|=+~FfvRaHSZKxTLV478!g*IYc&<7qR)FWad@z_fk#`kMm0 z7R_Uq`*d`-3>BqWIRv|B2Gj9OKS5o4FlpuPehfMrfL8xtK)UBh_9O&&)@-yY7^)+Y z*k`7uPM~atz9rSSom6cFcNh{)L0>?b->NStZT;wRo{t7BF~tX=x?Cof4F|AuF!T$&o%g0HF(mGkHmC*K6d?hT*xt z=>-MZF1Y#tq{d|FR`4s>LZMDDVbN{myQYkcqdKx?DMyX&0t@m^ot?wbBdk|r%7FQG-*sZP>98%#yh}3f#t*6 zjaMh`BaF@$js6#Ni+a~DvAg1cp4V?HpKSg0>&2)S2%62%lma8Mmhj=jy+(A#kBLYq zXE`gooO1#E*$RO|WUGM5*!Iq)rm@+aPTV*)tRyC8%JkMN`~G^14yX$Ad5o4L?cx|@ za}c;F^uy&VdXi@1X%(e>ECX&`b=hrO*MfCp8~2|;TM6L{OcXMgibxnm&l#$*g9ND- zCR5CIn-7LSv*N(XNXKM;{?WWw|Ka@c?s4?;$qk4&K}bx>pE-maL0bm=K8rLyF_DRx zx&Hi4cu>fv{7|ZZXq#d#3rkD5A>Kvv6%!Z%Al7jU0#NpY4am+l7K+>bAY}+kp-G|0 z%5A`q_yih7$OIxR6i{L*_hqXMEA7|0nr`4^oS0NV1oIx=^7mJUNmeCg-a~}#t)XA7 zX2>DN4Mb?%iyjCSYnPLtIXOEMrg?x|JSsd3)5ys#DK#q>m*eULfB<39Ym4*5qS`<} z;4QjWaC-&+nJaxGzGvvE zh`bFV2sn^1gW3UDPwhd`Tju$7_2LO?yg24frwSN;@77k~p{EKuXRV2#M5G(4K<00# zIK-g%FC0t&S#E5+93_V<#{0*m+s4Kw~ow?f^B{-1a7%mXwGf=qLYaJYY28u2sH)+HCpd0ua;DTkYc0oFEEB z(C3>{c=k9w{PScBZNXv4j@C6%_5p2 zC(PP*yg#pC47R@Yf^O@9lpo!n?d|z}Qe93%P-H?3u5Q4%As!bv9K~ggHiYPDU0oeD zo`C=L>rpX!EJVtVh)K~C7#Q3Jx2MHB4XZTsW@Xcf@Y!N(Yio;(H=&DFbnzfbkmrYU z7ZFQ6(;ER!wa+ZB-Q-CL*6ZCpS$@&}u`vW83U;0C*`1GzaP_#~fD&My0<+p0s-QW7 zx~Xrp_$NX^Q`gFa0(Tj4%P(m3)QTrKg~=fQ*b!@OvBDBlsgAL6f2VTZq8G`BPvuHp zK_3xAlzJlNCD)Eu>rab~`lR_Yld6wZ-u7 z$p}&$GGoB8b_Zp;{zAA|q+CXkyJ1@8NHi1_=ac%5^dIJ3`Z)!!FCc75>8BUI1SK0> zuv$2iCJ=R30hHsL(;l%Aj99XpqjG=If8U5;{vsB|wIPawA+Yt&2ZfI+I52VL+{lLUAeCJx4>1{jj z>r*ExDT%%IKmhHRjpI>AY^5{Bz0lGnA()uJQ<0XIc8x?DUjb!P8vhLbc>qMU<>lom zr3wtb_c=Js0P76=f5=c;M{a>=b^~GM(vlMJfrBbvxJa3^XhOq6kMn|v%uDo8pe7x> zRIG+)!M~y=gS$g4^Y}QMgH~gE;(uIMo}L>!k&zi^qZtJ$qO*?_5y}>iS`%O-ysWr> zaY}?_11(50)?}Mj@qCL<{o6LjU4mmK3$%)4fJXm+*g0tFGj>lZ+3BlHYkwIxuYemh zO)9P2{={}>4GyLD$`EKiEyV=B1}uju0xa`B=IM*_8|Xm6#xGlRqnE-V85acuZ3XJM zeee5J0ei{LE_9FnBuH7)qc|$y>ety3j+gx(+elw|<}@I8#xnZI`S-Ud%13Nz@BGlK zqgD{f1j3sSadG;1d!;x%cmEBJE=3U?qCY$!p1b4We=lzD@UR3R6<`oa$wl{}0su%w zzK&sN^4dHNf(=lzVWwh9c+u7b;?lp%?{Un4kj2;2ih3Wy)qQGQ_jIQrAQo}d7st~d;1gu>V-^W zg&A*`l=(d8-MaSvWXVLtFMmjudriCjvw_IsC0~c-RL~}}oo@Wc1Tbvg!-$$~X!2A& zpz`{4*1x30MAJtikcPxVU)J|q=}Q1NGp*&Ft3vWQaG#MR(LKh#M-$NS>EQ)xkN&MZ zoxZAcA)tEM zY1W4~*C&Aghx@9t(%)kTvT*ZQxIOfa(4Z(W#;CeKU~JH;`MV#?4jH~dmG-)w_6wR; zyss$5sPm>G5C6~zh$0tLS4x~P3;l-kud9c;RZwMsoa{ufD}Zi0LpJn<01Sh#gXu3a zF@Y^R1y~m0^HQq&O^1-I{QC9gSVdJe)BG_#EmynVhTV6K#}36J-H%Z5x_+}?{A_r& zva-@g{|10us=wk(gcjUEX6VRQ%aDqqj(Dd> z^_$j|auPE)=$?T&%uB|oKle~0V6W*E-sSk zI%l8IHSAOdB-}KTk@wHw`Ha~)&4x3pzU>MZN%qhmgZ`PZwSu){!G0!AaAF8&^l6k< z&}|p_ki-zaus}kc8|ye7%*Og`iF-Lq+r1lE2TmDFh%Owu{OGW-#K=E^OrfguvA@}A zkQ5)=lP%T(yLbpW3N~*FrYJl#HEz@V_sYkZSXdo|DYwZ#(nia_NThkaCt=~|S%<0fNXh0eafz&7o zEml_2lIJS)=B&N9;IP{GnjUtDEvT3H;ltRzk^36kl?>CL)Eru2cO2ufK?kA5Xv;R) zhcHe*fup}WbeK_E;&ptcawOiPm&lDtaCO>L8W~i~P z6)4l#)!c3y8sj@oo>f<02}r>U#ZeBFeDa{+CcmL{8V~W@KiTr=Q_2@PmBKF~X`~Fw zQa{aCT$k8rqrOtOBAcNm^C~TQbpAC&(J=F}kfZ7$;fkH8c$z#8ojfJc{)Xmc#fL`K zq7HgY!($biUyGKD7}jL-H_;=Gm4ma@V|(#h^F9*K{2N?_Gj^0M7WT|{w^93gC3M}d z5;Eq*`^@sbK7a;}T)*Do3XZi0-ajDR-JXu`)`!57X~b+Y9bG&;5CsgUnc;Q*uf13O z{bR|);rs+pWxxk)Bg60+fI&6y6Wf>#N@}J=*|!AiVv7{xnuqB^T)vF*MSNqE&UBFrRlBNNJAAhwSd-N zz9;kf{wMc0IP79!8Gw!W0%v^+VoFxeQ=DmZD_#>Q;j3vm_OG#g!anKrUng9!2t7VA zlo;a1zqXSls%0uab)gr6h)GdW(iF7AoCVC_?%Wd;6oipUeRme~Tu9#n8n$+KRfoQ*Xo&R4H7p5YJ;`c2gWG@PPj@u6 z4}vcQc?lL4RMPKCzJYcHv6%so25GBg_pZGBd`h0=*iF0t{o~rm?)S2QbVzvT4v*Kq zd99u(%tU}3L2H5N$Do@49)tIqlZ8dR9MN6`c!OK8T=Dql{CuSh)ANr(=omOUXDsVm z)0NBcdto5oO`xw#QE}RILV%49$2c#gfi$6RC2YBY{wQ}Qu7Gf6Zm#~O8=iJ!AkaH* z_1=H`_AOWk!RhJgJKy0B0N2Abb`)b2An$#k#UenJiP+)p2;XLe+YeCIEvJWeKfpa5 zmHT=1-R=rx%0M*o*&iTBU~_PA1hKwgf@G0^XN67l2Q$tkmJcv?fP&AcXnu2j1p>>r z%woukt0W`i1ucCs7jFC7tsv^-BLyyAC#BV}q*=9ZRqyyE#gR@48Xt^e&u@-%! zV?GI+N0f;cc4SfxK{k5MkFWDu(eQmGaOz6QO7`}gdV0cByX*GJuD-s$!$$WCs-YRZ zy>9Z~JL_Iqbv!wTQ6(DB+rlEZP^d8ZEok3ZUX00X%*g^-WV)~i2XlD@I>CSCTE)an z0onK%L6D|-c**lw6q|D!G0)}vC&PpdPz$Xwy_0I3<3up4&;oZ4=O({Jd~40k27I#W zCa%dWcLE+#PXB}lko&r>+f}(ghzi5`R>vtWjY8>9S5hAXBcso90nRoytkG>4W1Sa> zH|MFAuW_Bwj}N|q2{1R8ktS>*|C3TK==AD3ZqPl7jIS2qXsel=@)*jYphF`I_Ms5??b|1j6qnseX6$@I@Q?a$R<1i zr;OWjwcZ0D;LiWu^b|sUvJceP)XP{+9UaB&rXQMMtz~CNl!!c>sO5g}9`oP@m{~=e z%qADnLJO`A3xOJ(_Duj7S#=;+3bpE{0tILj#kUy z-Igb??5tVsVVk!eS+#8vbuMVSD+1@1Pv`sJp^_?+&Qy4~FH_^<0u%FY#)3(W z!V>-A%ZEA1WD}o)4+HlXDEGvo8v)o4+L32xW)PzanB?bNQ2oF;gi#j)>*kP`n?~K( z+^odD1n4(FXdU@~s7{7Qm=Q zL=X!h#Y;+7M>i3^z=gQB?P!)v2M2xG>G?SxIgj)qi>>YEQ(9kFSY&YOF`}+06qXla}cq-07S*E;u*A>RJM?UMYLIB|7rxo*r13Rr34hizX zKUusfke9&uErTTL<=j>-1Q%bz&aGr_sI35m*z$dZkfS9eQv-xz{`>aN;}EAni`3z} z1a!DOGS6{pkzGF$A_Lhx@=gR~0w})02G1l6Dyyp079x_s{ebM)gS$r3%DuzGHwe=J zGhXHWND!fkZr=0M5SB2N@SrVRx|PN~7B*JgO*o8!xOio(b#Bf%0bU z*lT0$$fBS5AiO(-SvmcQAsmmBVb4O4M#x-eaLN}zoq~00MBNNRn5o2G5G%Z(rGd2y zYi&VvLGReU(`riO(0!8}NM5r6>5m2agc;nYI)~{!+@xDif#3CvtOIH_1tj}%NGm08 zLjk5L${_QvUabsKC6!5is!L;wd2j}#{|n7uZ!?C>5LGSf`nIn+?9Xx?870KQzz}EI zhn-feD2xHH`QQ$y+FBvfGk-ullkx3@XU_{QZ3>hX1UvO9wiR23lm_Vos z9Qh)FcXnV25(GF|8*dZINZB`75c0%6Ba|>SG<@W^Kt)X*g+@R|#^U|7zaVBZT4jSn z3gb06Adm=m8%S`_Bn!PZimd$>C({)9zb}|b180O-mLJC=E;15_o>Wfdjx>!FpCsu| zNDLcxe&rFl0g478p$;TO#$qlD`5bd}lxl^nMYO_lQkuy(`w={5 zl7bREPt_Ws8Lu4bx)pF7_u)eT3KjwxsjcN?XO|KXh6%;SrVwiG2P4>HaEEX#Y-~Y= z#i-3sbRoBynv0$mYzMccTeoGSIbmr|#MmNYTh%_emCMS_HNd{XeV7@W{RUDpIQKQ} zkmsd+2uNN5d(3jhDrWi#5{t0ls4_eAL8u`5G&%zO2_|8uI(Q?OJzfB3^-uryi(4YPMn(%W=fty4c6J=$3kVau zGNH1;jr2iBQFnT87VNR3#&c3keu(r`6fD9A-W1V-bb<6prZjuZE>pk}zCnG=0$D)X zI$=x1k@0o^32fgGy}r=gDuwM904z$Dg__021|<|iH{Cfu-}2=P*)TvAT+_IOPq`J~ zq{t^h*n#D1<8qN}XKpv~{lKAT22Rhs#Id|%=)Ro3SJt!QOE_K(JS6Qh$JfFxFQLZN@Ugz$Q zZyD~G@gL1{QtrR}#=ohqptltxV3s%dk&@!i_SOsbA~yMO7v2wdc;(XqNFU%#2+j!L zX(puCSU#7e(HB3_jl}fxUP0FGZ$zO?Dt*SvyHVN;Zi+XVGCB2^t*dlD#yf;x1Z`$s zVKQ!29-0V>@AYBR<4LAoZB$M8c;~b^h;4sf>q5fw9xfRF(YcxwUoxvUZu@V+bl}sf zaaul!+u7!4odoYl`?4M#!HZxe?c$(h8XUBcS`!_P95&4^SwWWc@9t78^#>^a? zsgYfiKZb`b^cOz2`Y)FlO(PbB7T^NqixLy8FkvZ?s89D*7CSAKOIkV*=D=!i>4!=#`OO2e~d5*oDf+^JssT=j8|=q zInwt9tB z6|wbhhAnmSH)m}2nrVkO=iUOh;0}ICt4yB2lC*}s=jyJe8!lvTBd6+T>HV_%b9cm< zuHdkj--<}BEBOzLVf)dxC)h?_=Vx9@sLuUbR%^ymo!!fy6NYa;4lDZU)~{9X?}jT( zdNcCEA79(5_VwHL-vI-h@8nV#OKGO+osUz6J)*m_O-4STppvu7p?@MN*LXm4u=NU4 zhJ@z8*pum--0t&@kpxP~T=ZGP@&~pezBt(*|BA7<5C4!cS}O`4`|ts!VO@^ZN6+Zt zFmfDj8qwD3_Qs2dTJ`uQPF8OI@|NJL6a7Y)%KB24=dgn9ekLX^ZsKZ#Qbex8bHzTE zBDyy2qrp&tbX?orm;X?9mKEqk3NtgRP?6hECkDb;gJuSkxmqUz8nKZXj|{W7gb+f9av;y)j#x1ZfJatcewtH-xf>cZ^%mn3JL{@ zzfUQNT(Pa5>5nb?3TS%QU746Vw$qG$Fu4eOo9=0?cl~NL#9AchI65=DVx|6mk~gOz zt1+j|a+M~vf%k!Qn-47xu)*fpX9~T+iPFGYqRu=_AH=&^(;EA zG*FMIQHR%7Yixrb6ZQF>@HFjH(<}0>jL)ZzjZ9+o)rJ_9Nx!-jNIW->e%Vuh68V?T zL`UcQd_ZxVdGP?sq%VfJj3(w?g_0E z%UX|KNk_54ZcSS?`HzMy&ey+XBsLCAx=DyWM&C$Ex|izD?@L}JCYLg*8P_>q8|H^D zzACYn38-5lXKw2n4qY=M#ig8>vl#rS7~?~dp8g?sCqdiTpe?^M%Tjb4{C??AEW5xAZ@iKM22R&bMv;ZDg1}T5CJ6FF34MW4`2i^>DNT z>+&jYvc$nf9XXZz`b320@qFPKj`gLBg3n2wyS;;PiJ5TunF2}ZmyIs8E$juPQ!Z<5 zg8{vH?@BUW+wa)e!#xq*4JQY4b(TkY0`;{~2PHlv!|6LYw!(=~O?pmyb+yHhECl?s zgVPo}NJ+dl7hXhI3gcgl)$v=aZtvV1^!V02uM(GTIO?-G)on5KoAKb|*7evB$;RXP zMaSh0{=wABKH=ALZ#vI>r!g<~erA2B)xl4*QMj|-X`U;4;+22#P)@IwEiHS8!7sIzM|$mevZ$HtKK65atF4$ zcwo;s45|+l5rzg~j@1iP$)jfNM+2J!lv{c8L|2|~elC_4i@&2MGVW3`y1xElsHyhU zdf|glv?#mV>x~!-tGfe7hjp5^m!IOoDSQ+KhA5)+ykD&UUbRnGot!3;Ig=a;oc(!t z>0Z8Wwf<+DRT(_-`iz{hj_;jw3d^N+wMRIHjX5v7&V+AIdj@eC-ZN&D)F589TwNiF zpPUo)v2N!7tn_)|JiFw9T(l3jb|ZSNJP{3fj%=*uRCg5l*lt7-`yb?ps~R7YN5@e$ z=`0Bb;v#&j*lYGG|(LR20zV0>Tat|DwkoA`g3vgOx1tGwDc!a zRWHqU?M{o9mB}vcOogs1r-opIr;jyX*-IP#PsY&!-zK=p1@@7mQTL}6>brd7OG`&XQPUT;*L^bAp*Hu*YXtcY$-0-6;7&oFN^mbO390J4hZpbm@QtA zx*qSJR1F$&F&8M+imCILPKuY2h7S$5r@usc2aOw67o>++Zs2|0|qKry#adL{f{ON^k zbns}Js81azwY~W%u%pp)BtxQOEnb6T0Ohxej7-uCXbeZK_vRAcCK2={rIf3 z?A$9b6rNcC*hM7k0a29KH<)8)lf;rfZD-gCyEkKp{N-iCc5A2>IZXB`#0}<|-4X?P zp~Hg%Pt(h;b$03uN>5yg8}WzU$@GodQ8J4?m-;6yAEZ=hA^$CQKV$r&pjT=8R0lQ~ z%}3a}QddOAfBR;0kWGv4QstT^?60+eb#|YXGO6KUg-=KOQ?vKPS%<+(`2eHDmnyy` z1>#DX$3-KJbZ<3WOX#?iJ<1Z&rhcOK5pIQVxfL%{C^(X{Vy1q&lDd+%R6FQX?<(Wx zwsm7?Hq*}=vv=9U8;$(FNr%LrwiG#T-?ydb9WvnZU1cXPMDUAK>mA{T5Am`d-F;EP zCi0ge}@w!(5E-s?AD9Va9C#+yKdj^43~zolN7Y3`AWu3SJfz`hRW$?w<(0cC&VPG)hb z-tPB>m{FU3dv)XH8l}F;1y_NhADsE}0!6bJQ=?A^QN;ee|4Y)lh&Fv#thE_nC%Zus ze~`$LmhW*#jHq~ zN{5_j73oR$=lveUY9N=yz)bcE4al=L2oO~9tn;GUAZ;QgsG0q}ZNW%KjQz?5(!wQH z3{QFNet!6H=Q5%PXr(i7y})=$4tBP)E!B!(VfpiM520Q{eB6vC(hCPUBK`Ac*zCwE z;f;9ZvNY#C-lWrSoiK-xwchojMxjk-0#I&b}wBPblkosYO;U(F>L0<-1Z_S zhiRoLeBfK;vC^pBll6@(`#HRU4}K>3g9{&~H`wcrhw4aDwqa{@xI*6vK zzeY%(RE)G~Ky<>4j|KI6XPN%gR?vK3b5QL&n&Dw}{qTh!8^;O9x?W}B>O{P$WmbiT zOy;&EwsvXFd`j(ZWB z5sADI@vxz+goFvu`B}Vag}yzL=#^~jBg0|>KcEbZnurMOtim-59UaBWj0|zPK&*i~ zrkQHYe3Fl-`~8%d25{;wT755I1Mod`baaNAMqBBX|zkFz*Z#8 zzkYr$zrLNwk|`i;Nk^TQU|boGA6Hwi$F{GZ+Am)+7@k3gzVv6qoI&1ugH${LwUE4v zLgVA7Jg(Q4=aTC5JGDQWt+_pXE9f0|$dxcrJ0nICO~;`0@LwXhd*z^_FEt}5I30HImY~VUtsiwwT3@K` zbo+Jkbb(!yOITy4@3(g4=I$&*LsfUb{y|NDoOC6(&!4xckk-esSf49@KaLqMuoIP{ zH6~{>w8iF4i;dO&MvH%pdc?DQ*Iuus0^NH6q*8k@uL&iQ@34CR;pDPBXu`pdB*F-8 zkW>%`jtWehD3$C^Z`pCjy3)~G@9)6cWZO@1xv@QZlWz%C0ENs4s)f=jUy6i(yUXsJ z<3QA6yhGN)j6t+OYiPncvr(Qs-90qmNl0;G%t0P)GXL6vW#Bcp+HU4G3A9K zywl-VnznpOa*TS)Vx+A2^8YG3{d`*L8f#59irE03US1FwtEFP2bYRogHq@OsAL)yv zs2Shyct$kozC4iQkkJ0o5My!jtL%p5gr;UqtJB1Ud}MWH^(elrTbBL-U1LE}))B6j z;adg=JZp_HgJT`o_xs{U_^SNhkkFwIeqSw%4Ne(c9d@4D{#I*r;+M=J3e*=v^d&B9g|L&;RG^&#Ddi6))zfbOrZd1KN^4g+cybJ?12Asgu!I zy3@13I}MRPqtq*WWo=^?>Sx`b{gZ@*EfAlR6+1i0<#`#sZq1fC`^a!rTvAzMRb#$V z*B08hsmawUZh4khy8cf__^5w&bW|Sw=j*xL!kp(VhsmX9spvz98XTO=@z>xbDqbhuv- zYmwxZ8OMIi_~|6Ryi!yZ|3Ix~T&u?YD*d2xA#Z~EdE>})A9OCE>>@S!*LC)fSUP{p zF!S$R_ZccTR$qAJaURvV|JPAftZMZI&J^hhE3{{oUWq&2PSdA9>e*LY=vA2illAYU z$H1qU5N84@c35Xz>_RrQ%`9)h%*rZsr|{uDS8+&M=mExhx9>f!shOEQ&f~+0SBO2- z3GCW{K&YP)b=`9vgv7OrAYQOg!b9fi9e}w7>%Kh9YHx1`uh1WYN`2|D4qzU(k=uMC z${}uTZ3XiF2<*rb1Jk>{Z_W-@VFe5}LnC-9i2iJA%TB_3;I#X2BKM3~jY}i=gHeAm zo!+$1xmRyKMZ(=RHs2$Q8FH`FS#7V|p=b(iM0Q^y3l3jPB)Ap_jxs!vySSVk#I*B%& zZ+y7p_588d#pC)*tQx2NV~<2-LyjjZqv*()mls7O!vaQ{TJbb22~D5m`(zv!yE4Da z*Qq@I9-P@IfF)&L_&{pvUlei7!pXCNIyL%vx1s*d%pa-vxP{U$pViS!pHk!K8|rDy z4lU4MDJhdZS=tB*WWyUeem?m*__cc$-{Vq=&1~m%O`qC2@>xIq@1Nt3iqn1eT6>n= z`Acq1X+3y7`^AqV?Mg&%W;DkZs~_99q||ndOsVm_s9CvwA;ZpqZ$b11Tk=e(bD!Ue zTQh0r=#lV`#K`QZ|BmmCkgpt-f4B8;EKNcO$Ng@;{6FoTXEfaZ!=@#Y2!d1+f{5sy zQKFYfMDKlw-g_tbC0Y`_2hqDR`ixExz4uOZMjyTJXa4`^+1<0}?2CQ3=h=PX1!fL2 z^DUop-Pdi!l+{p1@6>&+rXcLTTNXNmP%UkgbJ}U<_Q*F&V>e%h z0A1EDc;6$FO|#^8hlS!7Y6sc`TYb~EFAo`5X%uR#k|lmO2b3oscUkLxrC#e6>4tU8 z<=hNM8&z*qYoDPvh5~k(BCunPnugd25kuqEpLsd`SlJj=ewb>J%&^+4y&wqCzeCd5{DFoeUr1_LE53w&t>cC`9&cS&MJ%CfwoBz!I}BV z4t>c{n(3&6?4k%2spZd&IZz&f;yuX)bT;n~E|v4P-s)fC#C@q_#;h!Dr~UfRvvk8V z79a-B2aYmXe;1cYG6tt>j`f_rE>Cm6WTFR6B2ykciNnTzBa}>?EOEOP=997dx}5~L z2PUv;I!F2PcmL4d>?t#AFU63Cd3Uf>Y|I%Lg!gieBe>ebVKR8juQG=GQSCkg@ej}1 z9%d|x+U8RoG0qCZ2yF&6nYXTXw9f7K&IXNy{nliM=c`fOX#C}$FqkaQC^#^nElIoP zUA7GR5~$zEkezw^vYIzsOaIKg(}sBAZ=l-6>LYOm_sS|wq-z@`6pfde*K#)d7@;UUjQ#;?*@=uGyRS|uSv2p}lF3`)~>HPDivX=cj2+dkRNDc7vWEnjG zJlNBb{pl_ejS2iuJ_oV;Xcam_){|ENMFR96IPuSsPue-h;RlYMg1iOJ~=m+;T&s&*TuPYG`YYw&v* za7neJSYFmitOh~~e}Dxv;-i2A9UA#t;f;SwSQxl<5@mGE8sDbhvaF8zl@u}H-X3-y z6_VA1Rl%%dv3ZV(CaPtIJkPM!-Y&{o4kP>Ky!p{0I{4L%P3Md1Ar~2D>tyWamDBmw zuNE#!i&J+Q5+vKnq4%dPTdWQwdq>edQ}uD_Yi~xS+b2y8 zqDHM-MahDxrPrFK$|z={jjn3^6#b3lYPklMY<;P3x;U^d1^G@c_8pmv!l2{DwuXjl`x<-dGrZhumyjq`o%I?xdJgefI2%rjiAWTX@Ty zU~}yTL^OJ&nK<*jXD@o z)UbdR9mcu(TC16D9Osg1YSO@RXx*UG~zf2oRvfM83&chB7oo~ zzrgrs%@8;5DhqF-*qgSj-epp*4)L5CCLvjn>|yC098~&wKTIHvACzSiAny*h(mu>; zFT_rFp8S5qVfF6Na6{RDcui7%+!tQtKAkv<%feqUD)}NITTB_A#s?KS>8#AYFRBb# zM`wf%)AzEJ?z^ht^ys`CSPmGnu^L;~zpSfy<#0qwwsGyBCw`CRaHLi|?O4>O9%e>| zhZlPn7dEcRto1Sr={)5B-ZD`a{)meAgCtjFpWcYJ)?Fu>X@za^bWiQtEzb; zQ2twg8}4Y%fhf4lV)1}(@{Gl273!H#&8ri9_eyvBb{*`J4K|P10#tpOscjLxi`n>f zHc7kWF4xEan8cR zdXwspMT^EJYu#)&l|pCrwVNM~tGnJ5U?)sF5?tNYp_@`>;{a3Ty(dH$TQCRYU?gb} zv7g#9Wy#(adk$HZIO74AlT7{cFXq|P+KIX6y(bB(IGZkM(uTx&T0}};ic6ST21Nn~tBOXF&lEVTqxfBceyg8%As)-c6HY|PJr z&vOOA%IYFI9BxftKS2eWI6`8=d1y6o>Id>g>31!xQdxTOlb;msW47wYEM$Tmhf9Tz zosY|Ypno#rHD`OPyS>UPfbdd(^i75LOdrlXNw}^#Vk1(GOilh3GjUBDVe5Nly)ol) zU~2KpSw>T>j){Ycio4j1DDD%5Mj<^xs>sP_ImN_*9DnPiz1X>W*VGTPuA^lc10GIf z^8OJcYRfX4YzQYeVKDzhJqz5yOi(^*+uf*3R6oX5u3O9eOQKg^{GTWf)4u`Z*RTIKCAdoM1qWlo?(NzbAoCprV>$aj zVt@?)#jvCJfg23C&M;O_P>@8@b_4==TH2LRGcd#d+udffBZ0G0a;GF?^(?Ea!Zxk+oQpfn{KoA%3 zjOL%t*)Z}~5Q;>CIn2&1NI(zg$iedSn-br89T%p_bE4KTE(;|)GEm!t8AuEXuzF{c}W~d*t3AqPEQZ0XC)RQkU0SvQ0l{}iHUWQ zaPk)y?m!y0dJD*&<|)g+%)A7Gu`uT8qw&Z31 zRT$v_aSc#Y7~&tOmzkSO*G0Qt^19-FwJ&JbRnigl6rANA>ye*BZ;^G5bK z5C8_1mpxdFbeIr7ZDF**BnScxcgYh3?RP~mM zE^8C?iI|uK*wS0x%^OWiu?LYQCW%G05f1h&AKpjF9Tdz&7>~=(TZgAg)Z*=`&mTpB zCklYSnEXaWgwhJj+s*i~bIjeNhcER-Q7Vk80M!-9JToAOkB9s?} zZ7Mm9K5w7&c1nDm7s!)xAtl5J9O zS;!FXY_<(4FRu>`c$JX@VAe(_5V6R6oCXPMVBnp=x8CSnVehaeet45CYhHO=25gcK9L|M($JZUF*}K0ZD`Oi6p*1tOWv zRS`9qG;D_aMe5CEZmzmD<(H`ukkE;g02r=Ppd`!FZMbxx#v^(Afm_*c?>rV1)e}b$ zSKs$#v}=Ea_s+Sl9zQ_fPD)i3U&S7X=VL9sn>uS3x&DIVz5$ASG4d3QxX1b&#D)X` zli860mIR>TH?9ymI*@>$6YItB-YuyK2?-c$s4LS`NsJ|6vSlX_30jG21_l&ge%qMp zEZr9M0!a1y<>QkR4MJ>;FILm?j(FjVr)&F~E85VF=aTZK+ zo-ZA>xQKjuco~&Q1ZIRC0p-6KIeFS>w%(2%r8;U(c=bZ7KE+i=!_jVP7Oq2Wp$s1F zp4a14pbPqZ45ZiAvohE~sSSG!t>PE4cJlfKu)Ilq!H~ju^AamL!;U%ZzcyIwgpN{H6XO^duS+A@Daw1GNbL*&UHT&pG}{gHnx9 zdA%Z7prBw~{uJn&3w$h~ z({{@obdX{!fQEp{U?NExG>7oLe&tDO$X<{p{owsvTPnzJ2b2jIwSS0wxlQ0}SlsT~ zB+Y{sOSt9tCBpnu*?)&Wr}cD^4Qbm|wg$zxM{a6bcxvm+@gZM@YTive|Bjd}X4R>0 z5An-Lw;Gz`GLEbCgWLanwwO>ymkFbqZ=?R)8TAmca%N_o3~_2<`XSB3QS^i%taI&33(9tyxxf_btX@cy&;p6;~~|TS4#}xk3?c{ zq;IkF@}4LpMEIo+&Dj@<-E8Nn?#?&rJAZd1uDIr^nc9^~*zvIT1l7ue_^O<1O*<}P&7->b|R?BI3)Q(psgVKevAntle-_uMO zuVM@?4=$*yw}JgABXWLQtrfDLBp@U2_iU09enFp^HPNNzYLi6RA@O#fCbWI z)wm3K9c|^9)P$78!NVY>V;>m})??(e?9P7Sq&JXsFykgd_}L^Qt6p(&b1-D)4Ml|g z45%leeYU*)TA`pI<7sr4RBwkZ+O|H}o^@Jv;{`w6ME|r}qN;_`4l?V{$QUcB`I4Z` ze-L-rZMp#g9sL;QZp$2*^#YFoec&8P+)$8Fm6b)$^_C+uZF1VW&He1|*@cJ9W{0}o z2O1naPUR@hq-%Fst!S~iK0;(%*N+}4`7Q*mK7+nCcJOc$wB$eSG;f#e-MMQ!&1F=lf_r3t4i2)9C?| z#ApU1ukB<(h|%%2jK+J<=@egRw#Vf*(aMKbN)|5wMjkwxxM0z$*32wK%Sp<`@ttnO z;_I?(qIp?$Vuz{(U0JWGntb$%Skb0UQ>?5VQnFplFk56+;P(B%Q25G^t*U@=0XJ8< ze?i=MNc-6@q21~o-7p<&cT+WF7aPQxm?xzoh=RUD_M>3qJa>@@1M_HFe;$ua!?U}zXTz89@}&< z?>tM2rZVdI3efpTjt4QK^w3-(M~A$%Gm6;ku1+<-o3G+dBHHz)GD-(}fuT<8LmH4G zWKGlP92I{36@*L!{?S4NIZ=J*1FPQOZF?VOB%$Rl)+LGOE0123oJVi*)u)B074F$> z!wZ+cJpRob0tik_gkz$rN2|^_rE+fD*oI^MP_cjG+J{V|_#=a*6>_gFTVc}$${~_+ zs^IsrP%nDGodpknO)EH#`InDR!-|XlO&#{-e|{`*h|0pd84I|>2vAzn2qM|jl|0tzeK#7FOA9c;uRLD@D`GeQq-6@8vO~fo zw-_eM!1&}vM`!oEZw+jQBeill#i+li*Ltc`(ZftH%BM@AB-%zf_3%WbMi>W-Mca*Panmc9;qDy=0jA^LhmQZlO<-uF_)sFsBN>hwE`D= zg>?Q&@qz`VZ{5Ja{|b(#>0&Hq?CXttuNCew?1P5^sRAvOcILlO|e{0><2~dDR@dvsMCOMHG%rFtxTJ1 zKC;B=7!Zf{YLgS%kQ{73w>y4qW4{(y>MpF5!~H7T#HMyRxty|F_wjL~!sy@1ri!q! z`4aFrnp}T?86i8Fgv^_6KM0O(5a!T;^?WqJP5csL6#Gz3!vTxnRb}2&oZJ#K3thE1 zR9btcWKZyB5=CfPEM6x%_qMQ`;APz}>Boy%YU5{0E|8lp#X#>4X9F>CE6XDx@E84- z*^3_w(M)Vu9X(1QNN1qtw&*VGpur!ERFWe~O-g7)Zoo%SKcY2?hhh&nl`GHKeC|#D z9s8AKb``zOqtB{_(eX$N1qeHhUZQOo8-d%Y;G>)UJ+_r+E2>W zd5r*|ABzP$COVe#kw{??D6YoON>QEtlJyMcOvS-PZKCqE9neq`BS1v~SBlu45gW9@B(VX%C-$b08QO;eQJiI7n4!M_e zjdZ#@Oh$qIYdk%YhKpxCvpdLv9{l(|p2C0gT&(ICo{RT?;!LLmF28+X3rsg$zU4WV4miNPN;*-R+kC7Kuyxj_9@Osam~P*6JFoYimbRIJ0e?S~W6CP@kbTIRYHs zfvPBF!CwWSfbMAgJ9*PTrQGBB#B=R*l3BRICIeiTPk>@pqPS7 zhWdR&{z}Q5>gM0IaDxvD)X?lUNk6ei6CKI0N?ADe+?U&IZEKMN*j#8PdiOGqKhf7< zFGyA+M;@$%)UV$joYx8&yu*}y4lQoT!-tlkqDHvc+CF9zETrKAg`^|DrrKQGn=5%+ zZ!J?p^cQ{$O%l7@vHq9k<9E(Jl2iOiCUFruZF4L3-XDby-SXBc*7E6-n+vC~GDOaW zj8aZV|BPXhlU_k>TT?F&<4Qmr;ndU|`I8Chv3Eb>COjMZ>|we5B?%Pz#<$VD1j}=| z8-aNu>Z)lM++oS>%pwQ~9geVesijObtBv<$3JY#N8e;S7YI)$bbo5eU3Y@+do#Qes zEqRe;vp{o%48~AP#9G-V@*QzJ0nzbooqJCXwscJ`M$o_LisZ~mrBU6SV>VOSHcO%8 zcKSW=M#0J{=;l~<97Jcvzbeac@XPtoR>nH|p@Z zTLpN^PDyUg!Ca5I4yPaUxEmrXG~)=1{vloZ$S=wSXSm8h7(a zN}83-`YRDHw_Gu+nz~2dv6<3)TuVjSP*tqeDbC| zne8^#R(h_lKYO$StrhKf^M{;qLPOP6+7CIz{IzA1t1V}T9c6?apB;`0c4C#O>Yknl zPoiYIU5Gz-B6u`%6Xn9giicM|yQ^qPGziU~PHtreU#u899Nj5*EM<>J_2hEOOD6}RrM7xM@;Bz(3yYO5bwUgu|_`#k$Sp&>4AWJz_kP2#|E zw+BhFAqa82@nKwUGX7lRzBbjnB||5W#P2mtG)tb`y<7|XUIY;qd|O!%5^yGN;j;NN ziG}qT!kxv1c-uH#i%`fH|hL}ogBuMvw$gK z?i}9Q2B=mgP$}v^ry*VUy%`obDZrNOL^HJO2_N*GT%U|m_m4^wG`-fDZbCO3H5edE z&+k+WgfkbP6fF9&I;8#(`qCWR6j3po%PnHw=uXk-$jsHPDE(tFS*8pieMeQydYYS=aio+BiCg{e^C+DKE z!Ctis>+tHm2KLlDQ`SRfI(Gh$4r;tIptR~b@~MiM%oCu z8nH1M@Cr_)kJb(j#ONI;)}yyN5W&>Emf^H{Mcgrk7tTA@Jk=)l-6H<&amdvJ0hEFScAXm5%@?U8-c38R6?#_P>~`rm@P!L2u~CxjJ5*dIos)#a`RVu3A^X!gN6E~#<}9T zs_}s_2fp~Z9U=q2p|P#?Fr8De{1`Ks(*W6+$k9thC8lop!JBek9UNB_#ymA7GHHdQ z(~pVjf1zB*p2v~%j?EQ$sJ;_En<&Nqx_V9}H>_xD)kHfy)hFB2NzGyF__WXNV**(% z6gv8P`mAeXiAkVvV=XL&e>TaPj)XSwy;)^Veh|%C81NrDuS7vM+QQ=dQoQ%~+OC!k zoo3l6b~Wef8A)<12bpIFBI(xpF@;gusA^3StK20dvSwpEg$p+%jyc4oXVHD z5cz$hwHB3!5)%~_++H={g#6T1UTG)K`i5z}&e2rui4;Zl8LC<%Tu{TTVX8GlJr5j_ zt?=BIyI|)i)eh11z-#m4dJ-%1%jK-2#_OZveC%gxI9H#nyuflR@O`{18)-TNj7(Wo z)rR+5FLS?(p2Z_(L03cD!=-Qmbn($@QjNU#NpB0UZD?N{W4^PBm)-n+5vq)ei&vz< z$Bj3xmrX&pk#oYcsF-H@8lAL@n6Gj0Dyzv~-C3gZv<%Ozayl9wthR}p`CL@Ya`t%F zWsdY^3UhX1Vsv|^3xWp5Q<0LgtA7Oves@0Lw?=qKUd;t@b}OrjVD23p)$o#TYH8|1 zAO0PsM5cIE3r(Y&$#%Kt8yuVpe|B-ZffLaM;V*x&xX@EeB9fFsUgKH6*&Dq*sk@tS zf+kOA#1Ed#(X~Ra|B2&YRZtIaUAVMrN1rK*9vt{BXfi{Vr=r^H)GDL9G=5wWrQSqt zxUVGhhN(#$p2i-;e;AY7GUzWRaD5Z*ql;Xd)V;RX*p2+4;5467J*ZIZf(Y!=nRIka zZa>#sFZ3c>6J zoQ*R|4wu{6Ir*K93a4!2Qx-h7I<}LjmpVCVHmsd?Wkv;c600?2QMo&m;?Qik`lJKC z2>s}aF;SySO)i7QZFnV)U1)$%f2E6RYT9#F&!ZFulDT>w=-fCs2EYlJ4d-?Je38ss zKr(e6$adsg#boB7sUSt2?sX1Y!r!_)WQ>(wPbR?&5V_h=(7%`(SH57~`i*H5*$eUo zCU^bIMUuw70Jf~-*)_F%K3N5YAl0#niJwz$>G?N@xgrE=S3viEnKXZCih4EE=zHVV zcmX{YB}O^gXk(Al}vW@C{ag>Vt@{cBc)&Sy96zsw0Ola0X7RgDC)YRBq*>!Bd%tRt~$8-8^kvSxgp)yPb&+t5(nbkvlU#Qi8pJ1 zpBq-;%(DXiYu!mK5?UM)uTwJkL6D-E#pX7uPy191_w7zg@J66hZu8v`q!Hb;I%~7` zOR|C+!ci!*WdOed=aHRIa_0)=FKSXJxddm+IcU&U}o*=*hn#?2$w1$WV^kml0~-~<6BL{BUQ5RKvw zNl8iZd`}0%eGWtIK4(@}zeO}Qe<4gFjHhT`2?xf(0L7Xcl2@jtrsA{;r9HzUCKWlH zyq-tmH|++$Z6||+TlbSR=6p_2vruSb9Vf4n&U8uD<&0X5+r`rLHPHvx3fbn%KZxKp zoO|tf-O_r@@_|wMz86!0LNnEaME#9E3&Yb(T-n+EEKl27a#;)OGK583t_*Lo)mll! z$&-D(Cnc7n-RiwfB;{CpLaz3%4&v?lMvhjZ$WgmQG*9E}s}!gET6MbH$XDBJ2}gNU z>Uj0&MT-8^b`Fv^R9f@PZOqx{?J-fel3!E4IW%B9A@a{WThDH7p7@)69qgy`{B;8U z7q-vQi>DnwOx`g$EoG|Uf24CWw#!idq;ue+fwz+@<;nVh>F)%n>ty)ujw~)3<5Xfq=o=zOxiuoWHh%QRV44xSL zeC-?th7Ka*v=0MsE^Zu_$8?KG!w5$^H zf4=-(h~-W{d%2i2?_CXNpSamMvM8^d-x z;arD`8b_@yW0)HkFE{sg%Y+i#_cBQ2(!geoZ=~f~RlH#5NV0j_m6wjPLvx)`{|co+ zMn=|%jxFADQ45;FH~Nc^q3G7{H|7i?B*(j%2`b&UKcn^^dUz8@xl=N$h;4w=yf6_Y zeV;^Mx>MXO36eGC^5cAs-EQOEiSgt6Z~1~!Zu$g@kFs`jQ8#~g!e~`*gF1Li5r#X> z*a;P#Pi$f2ho1g%NFpl#+(GqXVL|LK0~YaqQ9ebR0Yy2j%RX!t5C1{EX>(U6PM1fd zk3j97BNnv6DL=&`mX0~>q5jx07Q!=id;%`>)=K}F4IZ=p3UWxAifMi70Fx^us6VK$ zl`XN0_V+-KvI>ptl+K`V`Rth4n4wkvMpa6s|uO7FOir|K*Y3*P{2qbeZAHLoBRU%D1Vo zutc-&{8xDbp(RH$78bVCN3ci#|KuC+|6la~I4S;XAL{>iebU#ISXehV4@fH;z(waC d=JdnHI#neYfV=w+gP&l1l$3v0B>w5^e**=eD763p literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/batch-normalisation/index.html b/apps/website/public/learn/batch-normalisation/index.html new file mode 100644 index 0000000000..8f70b99f9e --- /dev/null +++ b/apps/website/public/learn/batch-normalisation/index.html @@ -0,0 +1,280 @@ + + + + + + +Batch normalisation: neural networks course, lesson 12 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Batch normalisation

+

You will learn

How batch norm puts features on different scales on one scale, and what it uses at inference.

+

Features on different scales pull a network around: in the spec's batch one feature is ten times another. Batch normalisation subtracts each feature's batch mean and divides by its spread, so the features 1, 2, 3, 4 and 10, 20, 30, 40 both come out as -1.34, -0.45, 0.45 and 1.34, and -1, -1, 1, 1 comes out as -1 and 1. A learned gamma and beta then scale and shift it back where that helps. At inference the layer uses running averages instead of the batch: with mean 0, variance 1, gamma 1 and beta 0.25, the inputs 1, 2 and 3 give 1.25, 2.25 and 3.25. The spec batchnorm_layer.t27 computes both.

+

Try it

Compare the two normalised columns; then set the running mean 2 and variance 4 and read the inference outputs.

+

Open the interactive lesson →

+
Batch norm: features on very different scales, made comparable
Batch norm: features on very different scales, made comparable ↗
+

A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference.

+

specs/ml/layers/batchnorm_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Prevent division by zero in sqrt | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward copied one element and backward zeroed two gradients
+// (placeholders), and the tests pinned those placeholders: output[0] == input[0],
+// grad_gamma[0] == grad_beta[0] == 0. They now compute batch normalisation:
+// forward/backward in inference form, normalising by the running statistics, and
+// forward_train normalising by the batch's own mean and variance.
+
+module Batchnorm;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_EPSILON : f32 = 1.0e-5;
+    const DEFAULT_MOMENTUM : f32 = 0.1;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const BatchNormConfig = struct {
+        num_features : u32,
+        epsilon : f32,
+        momentum : f32,
+        affine : bool,
+        track_running_stats : bool,
+    };
+
+    pub const BatchNormState = struct {
+        running_mean : []f32,
+        running_var : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Inference: output[f] = gamma[f] (input[f] - running_mean[f]) / sqrt(running_var[f] + eps) + beta[f]
+    fn forward(input: []const f32, gamma: []const f32, beta: []const f32, state: BatchNormState, output: []f32, config: BatchNormConfig) -> void {
+        var f : usize = 0;
+        while (f < config.num_features) {
+            const x_hat = (input[f] - state.running_mean[f]) / sqrt(state.running_var[f] + config.epsilon);
+            output[f] = gamma[f] * x_hat + beta[f];
+            f = f + 1;
+        }
+    }
+
+    // Inference backward (mean and variance are constants here):
+    //   grad_input[f] = grad_output[f] gamma[f] / sqrt(var[f] + eps)
+    //   grad_gamma[f] = grad_output[f] x_hat[f],  grad_beta[f] = grad_output[f]
+    fn backward(grad_output: []const f32, input: []const f32, gamma: []const f32, beta: []const f32, mean: []const f32, var: []const f32, grad_gamma: []f32, grad_beta: []f32, grad_input: []f32, config: BatchNormConfig) -> void {
+        var f : usize = 0;
+        while (f < config.num_features) {
+            const inv_std = 1.0 / sqrt(var[f] + config.epsilon);
+            grad_gamma[f] = grad_output[f] * (input[f] - mean[f]) * inv_std;
+            grad_beta[f] = grad_output[f];
+            grad_input[f] = grad_output[f] * gamma[f] * inv_std;
+            f = f + 1;
+        }
+    }
+
+    // Training: input is batch x num_features, row-major. Each feature is normalised by
+    // its own batch mean and (biased) batch variance, then scaled and shifted.
+    fn forward_train(input: []const f32, batch: usize, gamma: []const f32, beta: []const f32, output: []f32, config: BatchNormConfig) -> void {
+        const nf : usize = config.num_features;
+        var f : usize = 0;
+        while (f < nf) {
+            var mean : f32 = 0.0;
+            var b : usize = 0;
+            while (b < batch) {
+                mean = mean + input[b * nf + f];
+                b = b + 1;
+            }
+            mean = mean / @as(f32, @floatFromInt(batch));
+            var variance : f32 = 0.0;
+            b = 0;
+            while (b < batch) {
+                const d = input[b * nf + f] - mean;
+                variance = variance + d * d;
+                b = b + 1;
+            }
+            variance = variance / @as(f32, @floatFromInt(batch));
+            b = 0;
+            while (b < batch) {
+                output[b * nf + f] = gamma[f] * (input[b * nf + f] - mean) / sqrt(variance + config.epsilon) + beta[f];
+                b = b + 1;
+            }
+            f = f + 1;
+        }
+    }
+
+    fn cfg() -> BatchNormConfig {
+        return BatchNormConfig{ .num_features = 3, .epsilon = DEFAULT_EPSILON, .momentum = DEFAULT_MOMENTUM, .affine = true, .track_running_stats = true };
+    }
+
+    // forward on input (1, 2, 3), gamma g, beta 0.25, running mean 0 / var 1 (or mean 2 / var 4)
+    fn forward_at(g: f32, shifted: bool, index: usize) -> f32 {
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const gamma : [3]f32 = [g, g, g];
+        const beta : [3]f32 = [0.25, 0.25, 0.25];
+        var mean : [3]f32 = [0.0, 0.0, 0.0];
+        var variance : [3]f32 = [1.0, 1.0, 1.0];
+        if (shifted) {
+            mean = [2.0, 2.0, 2.0];
+            variance = [4.0, 4.0, 4.0];
+        }
+        const state = BatchNormState{ .running_mean = &mean, .running_var = &variance };
+        var output : [3]f32 = [0.0] ** 3;
+        forward(&input, &gamma, &beta, state, &output, cfg());
+        return output[index];
+    }
+
+    // which: 0 = grad_gamma, 1 = grad_beta, 2 = grad_input; grad_output 1, gamma 2, mean 0, var 1
+    fn backward_at(which: u8, index: usize) -> f32 {
+        const grad_output : [3]f32 = [1.0, 1.0, 1.0];
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const gamma : [3]f32 = [2.0, 2.0, 2.0];
+        const beta : [3]f32 = [0.0, 0.0, 0.0];
+        const mean : [3]f32 = [0.0, 0.0, 0.0];
+        const variance : [3]f32 = [1.0, 1.0, 1.0];
+        var grad_gamma : [3]f32 = [9.0] ** 3;
+        var grad_beta : [3]f32 = [9.0] ** 3;
+        var grad_input : [3]f32 = [9.0] ** 3;
+        backward(&grad_output, &input, &gamma, &beta, &mean, &variance, &grad_gamma, &grad_beta, &grad_input, cfg());
+        if (which == 0) {
+            return grad_gamma[index];
+        }
+        if (which == 1) {
+            return grad_beta[index];
+        }
+        return grad_input[index];
+    }
+
+    // forward_train on a batch of 4 samples x 3 features; returns output[b][f]
+    fn train_at(b: usize, f: usize) -> f32 {
+        const input : [12]f32 = [1.0, 10.0, -1.0, 2.0, 20.0, -1.0, 3.0, 30.0, 1.0, 4.0, 40.0, 1.0];
+        const gamma : [3]f32 = [1.0, 1.0, 1.0];
+        const beta : [3]f32 = [0.0, 0.0, 0.0];
+        var output : [12]f32 = [0.0] ** 12;
+        forward_train(&input, 4, &gamma, &beta, &output, cfg());
+        return output[b * 3 + f];
+    }
+
+    fn valid_input() -> u32 {
+        return cfg().num_features;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // With mean 0, var 1, gamma 1, beta 0 the layer is the identity up to eps:
+    // 1 / sqrt(1 + 1e-5) = 0.999995 (the old `==` held only for the copy placeholder)
+    test "forward_basic_case"
+        given out0 = forward_at(1.0, false, 0) - 0.25
+        when out2 = forward_at(1.0, false, 2) - 0.25
+        then @abs(out0 - 1.0) < 0.00001 and @abs(out2 - 3.0) < 0.00003
+
+    // mean 2, var 4: (x - 2) / 2 * gamma + beta, so x = 3 with gamma 2 gives 1.25
+    test "forward_uses_running_statistics"
+        given result = forward_at(2.0, true, 2)
+        when centre = forward_at(2.0, true, 1)
+        then @abs(result - 1.25) < 0.00001 and centre == 0.25
+
+    // grad_gamma = g x_hat = (1, 2, 3) / sqrt(1 + eps), grad_beta = g = 1,
+    // grad_input = g gamma / sqrt(1 + eps) = 2 (the old 0, 0 were the placeholder's)
+    test "backward_basic_case"
+        given grad_gamma = backward_at(0, 2)
+        when grad_input = backward_at(2, 0)
+        then @abs(grad_gamma - 3.0) < 0.0001 and backward_at(1, 0) == 1.0 and grad_input != 0.0 and @abs(grad_input - 2.0) < 0.0001
+
+    // Each feature of the batch comes out with mean 0 and variance 1
+    test "forward_train_normalises_each_feature"
+        given mean_f1 = train_at(0, 1) + train_at(1, 1) + train_at(2, 1) + train_at(3, 1)
+        when var_f1 = (train_at(0, 1) * train_at(0, 1) + train_at(1, 1) * train_at(1, 1) + train_at(2, 1) * train_at(2, 1) + train_at(3, 1) * train_at(3, 1)) / 4.0
+        then @abs(mean_f1) < 0.00001 and @abs(var_f1 - 1.0) < 0.0001 and @abs(train_at(0, 0) - train_at(0, 1)) < 0.00001 and @abs(train_at(0, 2) + 1.0) < 0.0001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // num_features > 0
+    invariant batchnorm_constraint_0
+        assert valid_input() > 0
+
+    // epsilon > 0
+    invariant batchnorm_constraint_1
+        assert DEFAULT_EPSILON > 0.0
+
+    // 0 <= momentum < 1
+    invariant batchnorm_constraint_2
+        assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0
+
+    // gamma.size() == num_features: the fixtures carry 3 of each
+    invariant batchnorm_constraint_3
+        assert valid_input() == 3
+
+    // beta.size() == num_features: beta shifts every feature, so x = mean gives exactly beta
+    invariant batchnorm_constraint_4
+        assert forward_at(2.0, true, 1) == 0.25
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/capstone-a-filter-on-the-board/index.html b/apps/website/public/learn/capstone-a-filter-on-the-board/index.html index f12368fd15..7e62566561 100644 --- a/apps/website/public/learn/capstone-a-filter-on-the-board/index.html +++ b/apps/website/public/learn/capstone-a-filter-on-the-board/index.html @@ -1118,7 +1118,7 @@

Capstone: a filter on the board

} // phi^2 + 1/phi^2 = 3 | TRINITY

Open the lesson's spec in the player ↗

- +

All lessons

diff --git a/apps/website/public/learn/cards.json b/apps/website/public/learn/cards.json index b9a9853793..73ec07b395 100644 --- a/apps/website/public/learn/cards.json +++ b/apps/website/public/learn/cards.json @@ -10,6 +10,7 @@ "learn/a-model-on-the-board/": "b9365e72b52c80e6aa910619129ab8c27e852be816b72502e6601176e62a6b83", "learn/a-neuron-in-chunks/": "a80bbd72c568fc1e67ec83194c971d0f826431931e6d5921f19856db016c43c9", "learn/a-pass-that-checked-nothing/": "ac621c2b8313caf55b562752930fea20b0b93f031e36c3ca808e118befd0ded7", + "learn/a-recurrent-cell/": "b886d540ec56e97ee85d906d87db66274e5580ad14dbd16d681d9417e59a96be", "learn/a-sign-is-one-bit/": "8a5aed2915cf9bb4b3e08c0409bbb3188f11be9c612cef3611dcf1cde46771c0", "learn/a-small-program/": "fba5eaeea36f43fc0a72cfe956a83e332e3317820097b101e4f2fa4a3d019421", "learn/a-ternary-alu/": "d3c7d028d7b7cee31b580287ad6dd911c2f2de637e95de0efafe0bade69ae087", @@ -17,17 +18,22 @@ "learn/a-tiny-layer/": "8876f29ac162b6a4056ef502b7f9df8d82c3db7e904a8de156f32739f7e1b582", "learn/a-whole-network/": "71a17cd60850a0f6e776c56fbc7e0d0fadf84cd19ba2f6fdb2b94cbe97d43159", "learn/a-word-of-27/": "4c6b28765d8aa9687a7fe5b60dc96cc05b83c4c8fb64c141278c32ebd7027a97", + "learn/adam/": "8dd0d18341e62cd91d2025733d2682c10953bd7b8a54dd8682696e3f3cd91fcf", "learn/add-it-up-every-clock/": "9db8a04a5a0850939e6ea7f4f04ce478deeeba842b9ef818d42daca563fc8429", "learn/address-decode/": "4b7a49117662ffbd5cfbfb3948b4cd5147f03db14d243842f24259f7b770acbe", "learn/ai-numbers/": "d9f22ce61d2271479c53486b027260f1c4713f13dc09d0acbdb20446d40d0f3a", + "learn/an-encoder-block/": "18f9e0dcc364af47a9eea1f34e7585bcf1a21784a8930da4c51c7f72e997ce6b", "learn/an-honest-scoreboard/": "f782a3681c0ebc3b23fed57524c87b069c354c69c55f9dd6c4b7139b188096e2", "learn/anatomy-of-a-tb/": "afd78394163c92ecf1c9d0f423f3d7f1c3f34380b8a7ffbb27e1f376950d3e3d", "learn/angle-and-magnitude/": "710e2aefd09a2d275c0894186d260df42194fd98128b6a3de74c7a66a081b80c", "learn/arithmetic-and-dsp/": "8ab7bc516268078990dda9c3cfc94468f2f89bc01a453939d1bdafd7d34b86cf", "learn/arrays/": "672a72dbc0dbd6f2369a486163c6bc344543b913524c03fcac74f71b07c033d5", "learn/assertions/": "b769da059ed61e29a375f4b745144fef3177e80c356cdc2563b95dc98a0a7950", + "learn/attention/": "c2b0c62c4c3e959d2d2e07028a9e65d53b7488f4178b16706696a82550143ae6", "learn/back-to-three-values/": "396c029632556c52a4ff5f3263e44c8a476d912b2652153f489c090f03a65f21", + "learn/backpropagation/": "b7d1d781f541cb03e5adcdc522f8eb36f72f9210b1b151ac247ef59ccd5dcc8b", "learn/balanced-ternary/": "5e12a2e4d2973cb19f2923d1ef7680f40af095f29a2b19591781709ad3da175b", + "learn/batch-normalisation/": "2fd469df5ddd4958c3ee1d2b7fb7f23c1a433a864dc3f05130f43d015e55175d", "learn/baud-and-the-divisor/": "bf7fa9f60bf4942735807a71c3908ca6c3a3cb28ab2d72b52f7caa4155fab4f3", "learn/bins-of-a-spectrum/": "6ae09ffc7d41830e838cb3ca5548babb9422582507ac168ade3efda989179541", "learn/bits-and-trits/": "5b8905423d672a34562df84951f388f6dda08c1ffc8c46dc8236a486341c4bcb", @@ -61,12 +67,16 @@ "learn/course/": "114756b262a60e717b24bfce2fc4bf2b95fad9475ec67128f0f78154aec6972d", "learn/coverage-lies/": "8af79b079afbce35337616aef7794f4459cbeeb1a3bbe6c62dcdfa3200078afa", "learn/create-clock/": "e719aaf80757a0091edfd4f6bc04fe90ac3d2fa2b031210b651d5c130c6ef981", + "learn/cross-entropy/": "cfc597aae6d3c2d06d63472566758ef6eea6702b8bbc1b63d39196edb763a86e", "learn/debug-with-waves/": "b1717ad35a2dfec9150f6aab153f8a65751216423595335bbeeb302adab78e8f", "learn/decode-in-one-step/": "6fa09311e4c180b2b0e223319ac0861f634125f77d306f8db70bc1a1fb7eb6bb", "learn/depth-sizing/": "856c69b8b8ada27a240ce23f9bc07aa452844e018945e8c3987d9922f0e4bcf5", "learn/designing-taps/": "97b5f1f00c48e9b300aaf55e8d941c3503709329b63b1b5e374a3d5c5863644f", "learn/directed-vs-random/": "016183c8433b084739eb3ce15e9e9a59b02a2afcdfa1105e2cc4f003c293da8a", "learn/does-it-fit-and-close-timing/": "490555334371f7df2191596c916e48f06b82c8a503504afa0afcc535cdf834dc", + "learn/dropout/": "184fa96f0c38877f9566757ac6afdd7d96b89f9d9e105c8385bc2fa06cc3a278", + "learn/elu/": "33a824f89b3ad0074669ae9e7013f801c382852880ccd19da6af8d08dff348fe", + "learn/embeddings/": "d50dc0e7d8074652c8cda96606c2e3c8ea1059fed52259b5828f2a30cce24e9c", "learn/end-to-end-scenarios/": "c27e513669976ea8d383d0684491c4b8e0e51ae7944ba00d8c9065e7c337c576", "learn/enums/": "b24db7fe9adc1c0a984b07382e2ed7d98d876a46aa8306f48319f3e78c522462", "learn/everything-in-one-bench/": "61894d75448dcf97c154dba7838861da4fba39878a7e6435b4d3bfce3870510a", @@ -87,6 +97,7 @@ "learn/full-adder/": "ccd65ff05e370544bd6458309651ff82aea15b78c5f6362055a54538cc26f139", "learn/functions/": "de7d459a95a7f96889c4a62a6bf8d95f1f32d48e8f70aeb68738733827e48431", "learn/gated-clock-trap/": "854a41ee11a04bc01f3e8ac85d954f9c8f44783ab18862f5b6d2a49eb9403677", + "learn/gelu/": "12d10ed5962b18d123f566f17f5b19194c8aa5ab88de8e585565a6839d722526", "learn/gen-ts/": "f9de4047d5ae8e0fafb1d932ba5e314dcbd77e3e75c2e199c40fc3bdae130310", "learn/gf10-ten-bits/": "9d38423643b0042f2c0c57e2d11701997a9c03f18f52d45ff455aae39627edab", "learn/gf1024-one-kilobit/": "6499e4424d0765e6d6b4fd97675eea334adb571071fb495e5961c4c0b1a7aa76", @@ -111,6 +122,7 @@ "learn/golden-model/": "d058d05c0bf78a1eb46db27e07fce81ea630dcd31f246005f45652ef4fc9e61d", "learn/golden-ruler-vectors/": "fef5c13c4facd7c3676c32dd95d75c3ecdaaf7c6b1702dcbcc2fa3c8a5de1b05", "learn/goldenfloat/": "ff6f9269c2bc7a545b01210ef87c245ddb91494ea4467d7bcf8c7b214a1a230b", + "learn/gradient-descent/": "76b26920c3e4995348fb473e447fc8152695e42d6a40989e88d7d791953d1f11", "learn/gray-code/": "5cdd822d021d6cfa9cd4d11bb260c8246f1282d3dc2516c3c0b39bcd81ef7d06", "learn/growth-through-the-stages/": "4b840eed202a22b6de29bd85e53b8081a9d16f413cafdc6a41425c20c396d626", "learn/half-adder/": "329f877f836be839f1d0bb8eefc54fc1253266c6404736355f29fff73603c581", @@ -124,7 +136,9 @@ "learn/jtag-asks-the-chip/": "8e9f0ea737a56a88be3f77f2a5bbd17f27ba807203524a41ef8958458e244e7a", "learn/kill-the-mutant/": "86570387fa43ba9a641df5990d91857f21c1a82ba8613cacf5a5d61d1637e66a", "learn/kleene-logic/": "b336960b33cbb16649e6982cb23a4dd9a3841cddc4281a1e0b302b9c1e677e50", + "learn/lamb-and-large-batches/": "ebb10b96e2cb5cbe4e14aaf9f23eeae8e5a1571b9627cefc2286f9b635817397", "learn/latency/": "168cd751407985e8185247ea8855e2f0f0599927ad039dd8e4ef8d387de02d7f", + "learn/learning-xor/": "f4d1f48f408e2b2f1f4815d33c6ce032ab7405d9d9594c1caa647e3b63121281", "learn/line-and-toggle/": "827020d9bd542bd2765042e39387966ac3d88fc231f33617ee0723ccac909113", "learn/lite-or-full/": "1b0621e7d65d8e513af9306a82b01026985cf7edded64badf2671c4481b9d272", "learn/local-names/": "a333213c360c685a4d8b8f1199c8b115082c4193f177eb46a5f85541195972cc", @@ -132,15 +146,19 @@ "learn/long-multiplication/": "25a03a23994eab0067ef5f132b426e24d3c80171d5e510739827106ff9473051", "learn/loops/": "5e55e28ed11694ed56b056b2457893cecc84e83691345062675260cd1597b732", "learn/lowering-the-rate/": "d719abad3b5a341339a2c0595faa9cac85d07153ad5236ffbf6ce8fb9fe32b0b", + "learn/lstm-gates/": "a49c6a0b5fe0c07b27f21a47bea65f4fd8d86a8b28bb67a61ff35ed10368dde4", "learn/lucas-numbers-stay-whole/": "a373643dd0f541fe352e0e33c8df7775b890fe3813ff479c76010375b9ccd255", "learn/many-tests/": "bb32b58c98bb9b53936e667ae4fd8100ba603a24254b082adbbefaf46b8dd44f", "learn/master-and-servant/": "7a80b7af39c8a2184a58ab4f163e33b23e848a48e5c3819be69fbf92dc2733f3", + "learn/max-pooling/": "bec9681374a41d450339a6972d35b181cc211395ee88eec1c229e4faf4dffa88", + "learn/mean-squared-error/": "3ce6f9b940f75d2f6b93d77eb506a209a468e6fd0fd5233233ddd97e4f0841d0", "learn/memory-maps/": "84523d7de9f700f7dedefc3e488bbea21bfa28147fa4d9318be91fe9795cc1a3", "learn/modes-cpol-cpha/": "df02f5c2ebe60c79ddf540d17d8367be1ef7ffb16da9c916da0e9e0dd1a126b6", "learn/mtbf/": "4c378b8ae7169558433f861d673fa25eb5697f5668651159202958ad6b1ebfce", "learn/multiply-and-divide/": "04f563d0b073aa75285382837ffaa8bdccce23df956d9d61002e2691224f302c", "learn/multiply-then-add/": "d6a0407858df178e9de0ccc24cded3864ac19f8aaa796466913a9f3713bf3fc7", "learn/negate-twice/": "d8723c28c60ec0e1b4bdc5255af07d23204acea7a126caa544c51aabc7153fed", + "learn/neural-networks/": "7855f1ffad9744a591df9c7eeb6af58949b7a7505e7956c307fe450e79fc4043", "learn/one-edge-one-world/": "5c3e2b05491bd8ac0f6f829324c830f0c3e7c44f7ba83af1a85b25645a3bc395", "learn/one-lut-up-close/": "166f3d723e87272cc8dfa905eec2ff86dc16c2fdef28c6c15988a6925aa6bd65", "learn/one-outlier/": "21a1cab7337d9d7c8481a6b31ea0b3e1dc3647bb8e16589f6f5b7a3c1eb291af", @@ -148,6 +166,7 @@ "learn/one-step-downhill/": "060b45a1ababf4d56f640e60d600dd955edf6559f8f8459891ecd604c513c837", "learn/one-ternary-neuron/": "9f91b48b09e93b6a1affb43597396e046d170b9ae9154853ab241154480c9b70", "learn/opposite-signs-subtract/": "2a067cd8add2ffd486c3bceca9dde5718d559ea05e2c98da89d272afba4746b4", + "learn/patches-of-a-picture/": "7d61c57ac9aced7e6054c6ab5f71066bd61f1aaa8a02a1a375484577e9cb01ff", "learn/period-and-jitter/": "4417739c2a8be60099196d5d8f21fe087d3f4db4a343d57b244a299494219179", "learn/phase-and-lock/": "b50b9c08c4a92c2ca46cbed1fa61ac9b517c45473a33c096e17133dd77801d9e", "learn/phi-as-a-ratio/": "68c557efb1a4c013635cad8a456cce50b90b906499bbf88f59039ee69d295038", @@ -160,6 +179,8 @@ "learn/pointers-and-flags/": "ce1f55c7f6f4087580af8e3712b333f3c6620afce158fef7fcbe74c1b90661f0", "learn/polyphase/": "12facbb412e9f761f4a1d784cd10a1b258d879331ed2f71bc80284a855c9f77c", "learn/ports-and-kinds/": "449aebb56d4f5f51ad3d2fc7b0fb8a47e051387735e1164d7f43bc266b7ba8c3", + "learn/positional-encoding/": "7fbfed1b683f41f661e22891e7d25165160f6b6b65c48cbc6203508f6b41e2e2", + "learn/ppo-and-the-reward/": "553c320e96c9e902950f7656c1aa099ce3ea6f6f9fb7131bd1cf8ade99f8ffe4", "learn/prefix-adders/": "d3e549c83d10e4d648ea42d7aa4aa5a7d29b1d92f5a07c3082cec0065de8b83e", "learn/psel-and-penable/": "982df421e053568947603b165505f6398abe14424dbd4c4e66b79e4ca8f4d051", "learn/pub-or-private/": "a556551e39a7d31cd2db6a76eb55baee0f702f9a8f16db74d5fdc050dcfaec65", @@ -169,10 +190,12 @@ "learn/read-a-bitstream/": "6e929c80a2d5849da4a1e28f16dcb10fc833a2bb912e62b2e2d2c410c3c1707e", "learn/reading-errors/": "fd80e7b6b9483768bf331dc6706ca2e4321b4d3b204a33c45d5d7fe9b863e66e", "learn/related-or-not/": "c964f27fb50b229360dbbc86e55f14a617aa191c534f7285bc7a8a78ae047079", + "learn/relu/": "62de22babc94f73743ba95532b6ca8cb168d4c08e32e67e64d7ba43d5340e090", "learn/reset-fanout/": "45a31086006179bc14b727a0d771f0ac598a880bb39f00b654459f1dc52e87a3", "learn/reset-release/": "16583af4595233b0c6448670e8a94b8395738518c3c71899a474956a36cb4305", "learn/rgmii-timing/": "0a35740b109c3a3f66fe201d5bb2f061474a7225768c325bca396e5366c9c9d2", "learn/ripple-carry/": "71bc88d6b49ed41455bf17b8461e4aa28da6f813b17d6a9106844c684a2a5473", + "learn/rmsprop/": "0d02c6bd58a357f575de0ff6cbfb950e388815f61c63a4cfc2ab523bd6bb62fd", "learn/rotating-by-shifts/": "3c975a7f97e55fc7076cc932b2b6111c3ec9169e579ab587fd51574564eb1148", "learn/rounding-and-saturation/": "0866fa53d9f74d03ec2c6109067bb031028f855498329f6b601804665eafb566", "learn/run-a-program/": "56ef29fdcc8424dbc1beacd0bf3647e8070105df1fe595435bc9d63549232ac4", @@ -187,6 +210,7 @@ "learn/shift-and-add/": "0fc9d1dc49e6aa7161cc37845eb83f35362705154a2a73d3c3a8f5808650672e", "learn/simulator-internals/": "edbc8a0f5538016c7b6a638296a2dddf2032aaf7ce2aacda891152ce313ef938", "learn/skew-and-insertion/": "a6baf709726e888f1066cdf6785a2b4ff2c0bd402d3609b48de1fe9decbd27ca", + "learn/softmax-and-temperature/": "1dfac26a22be07d9f66b7f23912f17331687bac4966bf6a3df6deb734e1280c3", "learn/sort-by-three/": "66b67912faba92a3dfdd14823ff8985d368943b2a1bc35a4146db96284818ed9", "learn/spec-to-verilog/": "5bcbad6f72f33199a8584aa06b7961177fadcca8ae10d0d9ec8fe9727bba9c77", "learn/stages-of-t27c/": "b5318e6891271ce79cf978df0f986b01c85a9ba3bbaf6d17293175dae43131e9", @@ -196,11 +220,13 @@ "learn/structs/": "12f9923befd6890498651ff8a7fb0cdf55f7bab8ceddb55872d83d891ab333f5", "learn/sum-and-carry/": "116114ab7cc7ce0c5b904908b524f2f2565c058e38978a21b3f9b1cd0760ad03", "learn/surviving-mutants/": "5eaefc28f2359aad770317ed6ba47b53dc718b374098bea1b8cf86ee9b29c40c", + "learn/swish-and-silu/": "27c3ef952edcea0f7531c3610ae0d780a2e3860a05aa460deee347a5e71ca464", "learn/sync-or-async/": "a53203fdb326431978eb2b306c84bc814385abf8e52bcd2de4dbb394e9b72e42", "learn/synthesis-warnings/": "4e12b31ade05969bc518fe065fadb711e8dae65e39d39a04c8cfd3aee2c5f26d", "learn/t27-number-format/": "c1e13d20ddeb83755c065d7ed838d54027e7f540642ec8c537b7bc1d9b052b8b", "learn/t27c-on-a-real-machine/": "44928c0d73a97388aa3b1793ec391999969384ec1cebd53e8b2d9bcc5d2f5961", "learn/tables-and-interpolation/": "0a10c09725ee7a0901b2ce55cdadcc07131adabc270838d3017ee8cac415cd14", + "learn/tanh-and-saturation/": "75ac9a39d9b6c25677e9036108d4c1c2204ede2f993df1f2445e9cd3a6a297c8", "learn/ternary-computing/": "c3b5ac0b20b38c339719c1c7dd04d5fe88055a16a471148e7913649002567bb4", "learn/ternary-mac/": "8c7eec502e24be9a72a888da5d43ec48d2064ffbf2acd70990cf8c9b3252813a", "learn/test-strength/": "de725d4fe191b20ba1f55eab08050eb7fd31a51c06514def130818494d1fa4e1", @@ -210,6 +236,7 @@ "learn/the-cic-filter/": "e9096d9bc30bd1f30960b0b8735cbcd7676ed9543e4837696e26941de74b7c39", "learn/the-dsp48e1-slice/": "f7f31aea3a13927f5a7edd06281ffc3c1979b41f6932aa9e45dd6252171eb3e1", "learn/the-frame/": "f8a52f994c8f6d9a68df9867b88d0d28705301fc214c761876b46b67abc9d3ce", + "learn/the-huber-loss/": "b21aa0f2c51fa2f334f79e60e20736ff6f11bbf227f4613c52694840dd2d0e45", "learn/the-immediate/": "50d7bf9de6d8360d5f2ba4d1bf07feab8e9e0ed753019a18d33117ce239c8e1c", "learn/the-instruction-word/": "14831935e16dbb46bc03c53a2c0987d82169cfd48246a21975a2c42102fff49c", "learn/the-module-line/": "7725a10a6801a0af37813f12f60489cae8e40477132e92e01ea548c921906b54", @@ -218,6 +245,7 @@ "learn/the-opcode-map/": "3e2cb39a5bb0d97202e07342de00a61cb2e68e005f3891519d60a3d1d7a42001", "learn/the-packet-bridge/": "8d67ce0e85853b41145108f3a1a5a011a4c64db7531ce8dbec6444db09c90e4c", "learn/the-prescaler-ladder/": "c302a7136b59522064c97851b5b548d3cfbb50a0a3acdd1f9846ba2f0c263bb6", + "learn/the-sigmoid/": "5904aa9031189bdefbf546505a5aa6f8f03f56cc87b39a96278a89c071836f84", "learn/three-way-agreement/": "0e6fb44f8c6c2f5de5f2a29546ec0d9e075b08bfa765c92d09306d2fc6c538ff", "learn/three-way-jump/": "409f5af46290fc7a48563787c90638949281b5a1728af9e4474f05ff442e590c", "learn/times-a-trit/": "2517a84f8c4cb482b873580dcd6d5577f3dac99f2afd327be6ae11129d80594c", @@ -262,6 +290,7 @@ "ru/learn/a-model-on-the-board/": "2285956627292be6c86d370ebee1ad16a5b07f62c8ebead82f96f490bd6b5bf9", "ru/learn/a-neuron-in-chunks/": "57e4dcdd5f09686a9cc7e2c19abbedc295dd5298e18073757e50a26abbbda461", "ru/learn/a-pass-that-checked-nothing/": "8ebe0c47613887dd80aa89f9727970c5953d360be26b70a0a166f7e8d2ae2df9", + "ru/learn/a-recurrent-cell/": "d2633234b6b1ea462e2b619c7075e432f351cf996203954f48a47c79f16c9d1e", "ru/learn/a-sign-is-one-bit/": "aab0eefed96d2317d7a7cfb804a9d94fbd601946b1ce699f9cbdd601d26bfe51", "ru/learn/a-small-program/": "ad8c3ecea45c6f884776eab43bfd8669f3d7e50daadc2df7877aeec24d6d5f00", "ru/learn/a-ternary-alu/": "b3a7bf73c1180a4ac31f815cee04e25fa6c3a6a0e7b021baca23bda6e5c82420", @@ -269,17 +298,22 @@ "ru/learn/a-tiny-layer/": "d27ccfcefe172a1a90e863f7482020a06115e96080e45c9807ed2be5999b718c", "ru/learn/a-whole-network/": "bf956bff7c76cb556bd5b072ae7f3187384f2fd0cbdc10d68373f0da7fc0251d", "ru/learn/a-word-of-27/": "1e03cd1b28871df3c08752e7db54e6d40db5ba6c71dc58a57374723be40ecb42", + "ru/learn/adam/": "f562e3ee7b54b1f713f9e50b49b2506025f75cccdfe67bc3b179483e247dd8b4", "ru/learn/add-it-up-every-clock/": "289375b6b343a7454a2fbbb41d8d2b13b40c9901ccb18316a2df370c0111a8a8", "ru/learn/address-decode/": "08c58078171cfdbb20d55768c98efa29a58e869761dc4d5401a028f0d221a2a9", "ru/learn/ai-numbers/": "2c3abbe2f6527300151af1755677e763daed3f7af6a80af188f134c45120832f", + "ru/learn/an-encoder-block/": "7882788e01d39206dd8d260ae048ec1308f0d6a9b93729f3797a26fe8f9bbd2f", "ru/learn/an-honest-scoreboard/": "a7a3612e27aedba4c0d67490481efd9d0fb7f4f67a72041d0d3db1ddf6e2adb2", "ru/learn/anatomy-of-a-tb/": "2b6d1945326894f983543e707c0bfbabb9ae42c0b5658bf58275bd23d8e8b245", "ru/learn/angle-and-magnitude/": "f13a34e1e362aab6f669d0579f5e95b4d845a78d57341b493c21ecc4d04bd742", "ru/learn/arithmetic-and-dsp/": "65c5de83d6ac927fed8e568b46dab25054ba3c13ad356c40cd491f1344133699", "ru/learn/arrays/": "0e6bbb8781017b1073bb0eb3b8be8664d39295e27b71fcd9988ae5cb8b49723c", "ru/learn/assertions/": "ebf46984f1df8e3ce1b21b643137cc3a1becd01255fd3e0cb4d9c145c4bd3aee", + "ru/learn/attention/": "d0c0658e4aef063126a96df015efb66af7f229482109c877a00d554add1afd50", "ru/learn/back-to-three-values/": "e228a4bfa47839abc0a2493e18c43cad1f2639cadebf10d983c1d43664b29580", + "ru/learn/backpropagation/": "583e1264d2c4f9f37c4a81c366e39dc1ee3bab9cca2a636150431da3dbf3b89c", "ru/learn/balanced-ternary/": "248e4d5fd125f09776cc8c2fcd230a79d4162420f36009be768fed92a0177414", + "ru/learn/batch-normalisation/": "ceec094ff0484f284af8feed10ab0ecc2faa3c00dcd9e1657510dbfa8cc53b72", "ru/learn/baud-and-the-divisor/": "af548bbdf4a83e3c46ca7222b3ec7f27f0cc645a451f4ad424cd1ea6dc08fe2e", "ru/learn/bins-of-a-spectrum/": "d4b066eb842be072984ee3f657ba09cefb10c77168cbdb180ca8687a9f3e0c28", "ru/learn/bits-and-trits/": "1e96d798dd9a87b446bba572df85b416813e9eaf55ec4952a36e0ec69050d45d", @@ -313,12 +347,16 @@ "ru/learn/course/": "b25e966436bc58071a5cfcc0bb4ecac778e9034151696377f2c0927c0b360a6d", "ru/learn/coverage-lies/": "746b6ca2452f95d06acd1fabbe3e23e6452cc4e506f3379c893151af4b3b049d", "ru/learn/create-clock/": "f463c64778670c5998d3aff6c0b9c35767c949d992f247636187f0d980469223", + "ru/learn/cross-entropy/": "ccb89a8438c5a9fc0c917c60ffdcb1b25843cf7833abbafe82b6516349c3cd84", "ru/learn/debug-with-waves/": "f37d1fc38708ed5b922160d32f95ba05cedd0c99627100525ece5a01c31af4ee", "ru/learn/decode-in-one-step/": "5892f17c8ad6d36a5a80f09925a4d985aa4612e21d43edb7d3d12cf0820e51f6", "ru/learn/depth-sizing/": "4742dd2ee5373997d691dc7148835074ceb0a2addae07cd268f5e77e0e7b9d3b", "ru/learn/designing-taps/": "a851b963bf3887126f6002b2124fcec8b54ea118742f640aca43cee7a40cd392", "ru/learn/directed-vs-random/": "b96e4b73384577c69cbd78bcef937ee2e79b42321db6a82b90b8af7c7b9da205", "ru/learn/does-it-fit-and-close-timing/": "a2d93b0f02bd61420390f9cfec445be3f3087cae45dbc8d18024a9c427a508d4", + "ru/learn/dropout/": "4438ad138cb41cfdec956a2b9ecd5c1083ba9f8d1f678c0f78f5fab1497e62c2", + "ru/learn/elu/": "f53329f213a925d10d3448767dd01a966aec2a22a56b1f6359947cfb79a22cc5", + "ru/learn/embeddings/": "6e1b5cdc0549e1dca8db68f44fd02e26ffc345a0c1a559ab1fd07f24ebe181aa", "ru/learn/end-to-end-scenarios/": "4637378e907d5de8cf6f6d9c81c11b1d9656b23503642bb67c156f08b84b02bf", "ru/learn/enums/": "5587fcadd6a785468dd51151e352a68826c5e5d090e6da47b0a87a776ebd8c47", "ru/learn/everything-in-one-bench/": "5c9630c3f9ba333054364ef7d856bb3c07d02f7e7befa99d45448af30b4013bf", @@ -339,6 +377,7 @@ "ru/learn/full-adder/": "3bace08ce220573335f0cfa0f35d5c9c9b1a952472ab2f3e8fe368f8763e12db", "ru/learn/functions/": "22c6502f7477353cd08c8ab8a1377d232d97b3348323ed363a782ebc32f73411", "ru/learn/gated-clock-trap/": "ca5c15b03434d4b6fa8652f5705945c9711464f42332b3b8d3335e35dd83357b", + "ru/learn/gelu/": "c34be30c86c439c3928cfba355fd372979616ac0bccee6d1586231fb24b99a9a", "ru/learn/gen-ts/": "d11ef995c9198a17e83571f4c9ab7663ca9669121b96c252c8fc4541e42f79aa", "ru/learn/gf10-ten-bits/": "8501cd00ab20882514e3769658e0f259f5350fe6a1a3145ddeb0ffebf84ed6bf", "ru/learn/gf1024-one-kilobit/": "f010bcdaa57b3d2ba464efdf3a9ba089b2cabf1147e8ef699146d15554238d5c", @@ -363,6 +402,7 @@ "ru/learn/golden-model/": "d6c8477436eb2a9a3c306e7052f557ac5fea8b5e52fa329624d64067fd771763", "ru/learn/golden-ruler-vectors/": "2bcc0aaf56e199f5c5a733ab1907c959400aa3fa161b0f125458da529242bea4", "ru/learn/goldenfloat/": "6bfff0e6ba61da77ed4445759b0939021607e02c33f2c760d758f0eed227a8d9", + "ru/learn/gradient-descent/": "3bb3989e03d2642ef7465dd317962caa9282f29f9684cd87e9ebb4cc25f958fc", "ru/learn/gray-code/": "d99dc71f49be203e39bd5c3a798b7de890617598d1731c6df4b679cb20cd7e09", "ru/learn/growth-through-the-stages/": "c51e900ab6924e14aad33cfa533144d8f3ea00e2ce65b49a87d7a19de1ed4f01", "ru/learn/half-adder/": "4367bcbbed7c921404c36238cb5fac9362ea1e4be99f9462e73f10e15cbf9f38", @@ -376,7 +416,9 @@ "ru/learn/jtag-asks-the-chip/": "64f16cb0c154455de759fdb8a5b18098edef4bfd9bceb73395fa252591f64287", "ru/learn/kill-the-mutant/": "6b74b02f6f7f649eff255521f6df690ca6e552c4e93d7ae764603c885e3cd1e7", "ru/learn/kleene-logic/": "c0b602212cbd1f1a2f9001d12473950bb86dfce63b5a58e27502930616d76f18", + "ru/learn/lamb-and-large-batches/": "51a67edb69ea3acdbcfeb859e3477ab2e22519739592f2d33b39d1aed067dda6", "ru/learn/latency/": "2bda3379451088319f72593c4297114d4f42bdc4b191e858e4c97b00dcf3c24f", + "ru/learn/learning-xor/": "e457ceb509fd5abf78959043685dff42036ddf0ba3e403570ea4eff71217e3b4", "ru/learn/line-and-toggle/": "8712954090e7a69827935be1d6baac0daf902287d13af875a50a80b18ab379cf", "ru/learn/lite-or-full/": "b8c71143785d50e53ffffb42bb3611f1bdeaa4bda4f7482cba106da6620fbb86", "ru/learn/local-names/": "ff79cc563e9f53dd044e4e5c7feba5b3e671a764c91a14acfcca28d431fe0272", @@ -384,15 +426,19 @@ "ru/learn/long-multiplication/": "39f6ca3bd75729a9acfc5256dc33c7834505492c2b00794c9137326143531355", "ru/learn/loops/": "00b91bc482aa24844ebb234a1b538f99814a6bc3ac01dcde951d5fba63a0cae0", "ru/learn/lowering-the-rate/": "a53524f5d7f23fd87ef6d3c6b3315872508ba85fea6f87f94685ed16e270627a", + "ru/learn/lstm-gates/": "28ea3d328589375de86c647b9be5a5bb7b5372c38e964c9192e394fdd5f6a7c2", "ru/learn/lucas-numbers-stay-whole/": "c5ef14808a72c376f6d623e70fbed43c3e728209c41fb6f12c953b371cca9d53", "ru/learn/many-tests/": "e3e15e5ed2ae09c1ae4bfbef2c936752029e6d3d230ecfe15bab2d8e66e10598", "ru/learn/master-and-servant/": "18bb7e360619aca822e498cb178acc29309bbafa8f14c894b79283440b945013", + "ru/learn/max-pooling/": "7de21a6c07eacf033cc682f663c396a97b4f5f7265984a190f1bac9c5ca793ff", + "ru/learn/mean-squared-error/": "e9b1e9841d1838aed496c0c43d6b13e3ba58987f14d3a88f41aa9087365d4902", "ru/learn/memory-maps/": "c6b7692933e91f8ab282a69769e4fed118f713f6a3979650df995cf468957fba", "ru/learn/modes-cpol-cpha/": "96d94cd7df315dec06357d08bf4f7f20022c0cee90d670e534beafe6793bd951", "ru/learn/mtbf/": "fa0c7a2797083eb6f7b44dcd1ea89b3ae560c111201ddb0376f899c235e3d2a6", "ru/learn/multiply-and-divide/": "9e5f639a87b6c2a3ffddc453c984a95292ac30ce64bdc9f5b55d5952629c15eb", "ru/learn/multiply-then-add/": "61ebf2be71bb9bc7b1391a9ce5f410442dd84eaeb529d588a35ca51501a9edd2", "ru/learn/negate-twice/": "392a6c948a48c4ab72b2cf30d4e1378a95408671c288cdfd3cc4e76569a7ad6a", + "ru/learn/neural-networks/": "e2c3701580205e96e14ab12193840f3d50c12e83578151df327a680e9f923f94", "ru/learn/one-edge-one-world/": "2259c1b021214040d6e338b1b806a2cd6220c651a45b8d2154afa534a31f478a", "ru/learn/one-lut-up-close/": "3f41d0df7387a37b49b04b2f443fa6777ed1bf02a72efab59ad537a31aa215f8", "ru/learn/one-outlier/": "c34f1bb2662cd52c783d6eaa53842331d3c24f6e6de7a2fb3f296650d4e0c463", @@ -400,6 +446,7 @@ "ru/learn/one-step-downhill/": "c2172182b46bb262978253fb942075fb0a35ef152f88112228957720efc4de27", "ru/learn/one-ternary-neuron/": "120cc517171191a4db21ea02a42604e03d7529ab9370b9e0ecc6a7c1b3d70e41", "ru/learn/opposite-signs-subtract/": "0a9a4ec69219b10e26620e9ef4c9f91834367ab7d65ab8fda5584880bb018622", + "ru/learn/patches-of-a-picture/": "4b4b94a2cd72fd9689f4ea1ce717ad369b8a06408771f2532437e51ee0b90cdf", "ru/learn/period-and-jitter/": "c8024fbd2b6eab7df162567b25b854639105d6fd3b23e3212238d7cb19d524cd", "ru/learn/phase-and-lock/": "7220b431dc84c1b629636b5bc75c28741fcab3ce516061899b15133ec07cbfa7", "ru/learn/phi-as-a-ratio/": "b4c3927b1141b34bda4f5adc58dfdf8ab1705bca1426c266af2536bdfdcc7bb0", @@ -412,6 +459,8 @@ "ru/learn/pointers-and-flags/": "c6c7fdf022e09acad94955e2fc1b2904cd2e6f3d7456d92b5f8761733e15ba8c", "ru/learn/polyphase/": "feb7fe1f3303ffa81abbe22ced62395d5b896b8698329a22e7de9606f489a37d", "ru/learn/ports-and-kinds/": "6770d4f5af9190e0755e7f43ba2dcfe75d2cd491626d4af994baa07b0ccf8c07", + "ru/learn/positional-encoding/": "65e8d4161a0e9e81aab1defcdf8781d3e50faaea94046676c0db21e8bfd14817", + "ru/learn/ppo-and-the-reward/": "19f7fa5a00502b775b2c861db8dca8eaf3750d6394e96d82cd87b2617a0e3e0b", "ru/learn/prefix-adders/": "4a4f0da43dd5baa00ad1ce56574488d3523fd5ee541c06950e605fbf8fe28267", "ru/learn/psel-and-penable/": "0c8db0a03580f0e280a3a589050816f537b87682d2d476236b681ce618334628", "ru/learn/pub-or-private/": "90dc28ccbcd693817876da6702a39d83d195bc379bc4fdd7a334f0f0d2fc9cd4", @@ -421,10 +470,12 @@ "ru/learn/read-a-bitstream/": "dd8e56af7d6109c70d3df54587a16457ff42b8b463a4be851c0c8544b1b5d5de", "ru/learn/reading-errors/": "08ad4f65e5ebb8133be23f8aa5aceaaebcb3c86c540f54b77935d140f1201712", "ru/learn/related-or-not/": "9eabcbec0f1d2fe344c6c4c3079d69a683d4d4008cb59be5377cc7836e896d82", + "ru/learn/relu/": "f499830dda1d7249191dcf9b7f90f60bd7b7d0a19dde57cec9b118446966ee85", "ru/learn/reset-fanout/": "e78a12590614ec49df0520220cd5ecab610e889381403317c45c19394a164839", "ru/learn/reset-release/": "7eb4b8202ea9143644bb7e00257fa13986827c3e1475f23e96e5c441647eac00", "ru/learn/rgmii-timing/": "c5da1b914f3dacd9aa298018073cc64235ca5bcc21b4e55e48c533a1c43f3069", "ru/learn/ripple-carry/": "69c2c82cd29b4514dad063f586e20478028dd0850f089d23bff50a7464fe0dc4", + "ru/learn/rmsprop/": "36f402b801339ff3058c74473457080f4a8816e0f517dd4d3901662cb77cf42a", "ru/learn/rotating-by-shifts/": "ac4a750f0d9416e9435b9033cfb74f71271a2525fb5474cdfff548b952ef799d", "ru/learn/rounding-and-saturation/": "f4904e10649bdbca22405a140c73dbca70f8cb13f4b3e86535c0c083b0d815ee", "ru/learn/run-a-program/": "8cbb40f7b76858ee758ab6fdd05e1a2d9e694a9a4b7b97e68a3f38e00af5bdb7", @@ -439,6 +490,7 @@ "ru/learn/shift-and-add/": "21b8b125f392df329f5da2c35025958705c3cb26b30fa4426c280ef4ecaf5b7d", "ru/learn/simulator-internals/": "eb52f4fb43d5013993fc65acbcddcc54c8c487ee7d3ac60cf0fae516bec1d5fe", "ru/learn/skew-and-insertion/": "875431550bd473591ca92fef039b21dfb8558a1fb642286f734fa5d3921ef074", + "ru/learn/softmax-and-temperature/": "863b179c0849b0b9d4e8e385b93b7ecd4f805f4646c54e6ba55f091686716682", "ru/learn/sort-by-three/": "927faf2bb422b3757fe04f2b68db66ac6dbc76a950e7d04dce04e1ac91f1d0f1", "ru/learn/spec-to-verilog/": "3712e4f92e2c169a9c89c45d5c022b90bdf73e501bfde4dd0bc4158a7233c4fd", "ru/learn/stages-of-t27c/": "38cd775b193c470a268a9338560ea8b2ead25bdce09030c8a85276ea7a5da66d", @@ -448,11 +500,13 @@ "ru/learn/structs/": "dba08039918a7755dca4fc21059820cc39d7bed801b60971bef428648bc0e339", "ru/learn/sum-and-carry/": "5d5314c50224b0492c133b289adfabcbb366383d576685aae34f84df9c60f839", "ru/learn/surviving-mutants/": "4b380011cf05e284d34b64e19c3187ba897160cf9809389756e6fd9fde7ee86f", + "ru/learn/swish-and-silu/": "2e5f5b445d241aaf24663cefc32144d22ed3582d5420c818651b8514ec487414", "ru/learn/sync-or-async/": "72c9b5b87e280caf2c253aeb932b270fa46524d95c9bcd9890981e7ffdc26591", "ru/learn/synthesis-warnings/": "951ba438de7e8e07ac857f3d7b66dcdd6d4ead4e3e848b36711c613bb240da27", "ru/learn/t27-number-format/": "e77c08a1a7a77548f1e2e8c432e91d87848890210c8b1b012c2923b8df86aa8c", "ru/learn/t27c-on-a-real-machine/": "0c7b40e135cb41870d4c71d42d0bdc5614b46b4f27a9301336efffaf07dad379", "ru/learn/tables-and-interpolation/": "2c573c7c8f5b7d35f749ceefc1f05f9f887c1c3ca732b6d3be9581a8d0a3a5c5", + "ru/learn/tanh-and-saturation/": "495d8a1e8e094e7c09db71675082f69263100078e2a318778cc0a7dfe4a3f237", "ru/learn/ternary-computing/": "70ced8c1a029088201cac11f0c42d6dad3762a948257ba915967f23addccf5e4", "ru/learn/ternary-mac/": "78a69adde95b30b14754a617d90bf487f86cd6a45e8ce579373e152858cba44f", "ru/learn/test-strength/": "b5652fad4a063c794dfb4f2e68ae1cb23ef1e3ead93e67c95ace3b4920daed94", @@ -462,6 +516,7 @@ "ru/learn/the-cic-filter/": "2fa2d18d844d01347cee42df32e370c411892213414983c3fb1b12b519dcb1c4", "ru/learn/the-dsp48e1-slice/": "bed22e7faac052e1e867e04d473e78818ba6d06169f121ed18f7e40a9e6f3b4a", "ru/learn/the-frame/": "67b1bea598485ead866b58b16931b727c495211edf0311742c9c60668499b68f", + "ru/learn/the-huber-loss/": "acf0722b9e86dbb95c06097c7c4574f5d6e89795d281aca1722ea3113c45d0aa", "ru/learn/the-immediate/": "8c46a039bbba3c821e23cf3a2a8d2e5d621bf1b82a094a669eaaf4d2aa122005", "ru/learn/the-instruction-word/": "1c505c99338c17d12117db730f1cc372f40139e6c4ea35c0cd570a33edb0048c", "ru/learn/the-module-line/": "64e925ce7f71cbd03711755222aad715d071a52a839188b0ec12573039bd8487", @@ -470,6 +525,7 @@ "ru/learn/the-opcode-map/": "5e1e16352052b3ea4155fdbc24b9736bba0457f77010399087ca0006b492b78b", "ru/learn/the-packet-bridge/": "42db292451ff065051853a1fe6e5b76cac209439865b0c04ca92d2aeed63a328", "ru/learn/the-prescaler-ladder/": "24f40c27913d09799de1f355979afb3c7ce33077c623afab1047ee5fce33e98b", + "ru/learn/the-sigmoid/": "fbbad14c4eab03da0e1ed1b0246852f0506eef804c15a67598a5796f0467b563", "ru/learn/three-way-agreement/": "bebf6245e54bf8c7bdfd9d0bd4333c1697f8e584edef789e25d94e4c58502928", "ru/learn/three-way-jump/": "f62cb714d30730385eb361748e15285092ef19461941777ae929aea1e432783f", "ru/learn/times-a-trit/": "a26840e4f613ec942520b27fc81863e0f3a88493b37cb653b395d51ae67a7a0c", diff --git a/apps/website/public/learn/cross-entropy/card.png b/apps/website/public/learn/cross-entropy/card.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd8122184b4e2529c315b0f042cfba0e2237bc4 GIT binary patch literal 50686 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 q9%nb + + + + + +Cross-entropy: neural networks course, lesson 14 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Cross-entropy

+

You will learn

Why cross-entropy charges a confident wrong answer so much, and why that is what trains a classifier.

+

A classifier outputs a probability, and cross-entropy charges -log of the probability it gave to the true answer. Predictions 0.8, 0.3 and 0.9 against answers 1, 0 and 1 cost 0.2284 on average. Being sure and right is nearly free: 0.99, 0.01 and 0.99 cost 0.0101. Being sure and wrong is expensive: 0.01, 0.99 and 0.01 cost 4.6052, and toward 0 the cost grows without bound, which is why the spec clips p to [1e-7, 1 - 1e-7]. Its gradient is largest exactly where the model is sure and wrong. The spec binary_crossentropy_loss.t27 computes the loss and the gradient, from probabilities or from logits.

+

Try it

Drag prediction 0 toward 0.01 and watch the curve; then read the gradient bars at 0.5, 0.5 and 0.5.

+

Open the interactive lesson →

+
Cross-entropy: why a confident wrong answer costs so much
Cross-entropy: why a confident wrong answer costs so much ↗
+

Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound.

+

specs/ml/loss/binary_crossentropy_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Gradient w.r.t predictions | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: never compiled (`new f32[n]`, a float loop index, `predictions.size`,
+// an empty enum), and it approximated sigmoid and log with polynomials that
+// were 0.3 off at x = 1. The probability gradient also had the wrong sign on its
+// second term: d/dp of -(t log p + (1-t) log(1-p)) is -t/p + (1-t)/(1-p). It now
+// uses exp and log, writes gradients into a caller's buffer, and reduces by mean.
+
+module BinaryCe;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_EPSILON : f32 = 1e-7;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const BinaryCEConfig = struct {
+        from_logits : bool,
+        epsilon : f32,
+        reduction : Reduction,
+    };
+
+    pub const Reduction = enum(u8) {
+        Mean,
+        Sum,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn sigmoid(x: f32) -> f32 {
+        if (x >= 0.0) {
+            return 1.0 / (1.0 + exp(-x));
+        }
+        const e = exp(x);
+        return e / (1.0 + e);
+    }
+
+    // p clipped into [eps, 1 - eps] so log stays finite
+    fn clip(p: f32, eps: f32) -> f32 {
+        if (p < eps) {
+            return eps;
+        }
+        if (p > 1.0 - eps) {
+            return 1.0 - eps;
+        }
+        return p;
+    }
+
+    // -(t log p + (1 - t) log(1 - p)) for one element
+    fn element_loss(pred: f32, target: f32, config: BinaryCEConfig) -> f32 {
+        var p = pred;
+        if (config.from_logits) {
+            p = sigmoid(pred);
+        }
+        p = clip(p, config.epsilon);
+        return -(target * log(p) + (1.0 - target) * log(1.0 - p));
+    }
+
+    // mean (or sum) of element_loss
+    fn forward(predictions: []const f32, targets: []const f32, config: BinaryCEConfig) -> f32 {
+        var loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            loss = loss + element_loss(predictions[i], targets[i], config);
+            i = i + 1;
+        }
+        if (config.reduction == Reduction.Sum) {
+            return loss;
+        }
+        return loss / @as(f32, @floatFromInt(predictions.len));
+    }
+
+    // A batch of rows of width `width`, flattened row-major: the mean over every element
+    fn forward_batch(predictions: []const f32, width: usize, targets: []const f32, config: BinaryCEConfig) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            total = total + element_loss(predictions[i], targets[i], config);
+            i = i + 1;
+        }
+        _ = width;
+        return total / @as(f32, @floatFromInt(predictions.len));
+    }
+
+    // Per-element gradient of the (unreduced) loss:
+    //   from logits:        sigmoid(z) - t
+    //   from probabilities: -t / p + (1 - t) / (1 - p)
+    fn gradient(predictions: []const f32, targets: []const f32, config: BinaryCEConfig, grads: []f32) -> void {
+        var i : usize = 0;
+        while (i < predictions.len) {
+            const t = targets[i];
+            if (config.from_logits) {
+                grads[i] = sigmoid(predictions[i]) - t;
+            } else {
+                const p = clip(predictions[i], config.epsilon);
+                grads[i] = -t / p + (1.0 - t) / (1.0 - p);
+            }
+            i = i + 1;
+        }
+    }
+
+    fn cfg(from_logits: bool) -> BinaryCEConfig {
+        return BinaryCEConfig{ .from_logits = from_logits, .epsilon = DEFAULT_EPSILON, .reduction = Reduction.Mean };
+    }
+
+    // The fixture: predictions (a, b, c) against targets (1, 0, 1)
+    fn loss_of(a: f32, b: f32, c: f32, from_logits: bool) -> f32 {
+        const predictions : [3]f32 = [a, b, c];
+        const targets : [3]f32 = [1.0, 0.0, 1.0];
+        return forward(&predictions, &targets, cfg(from_logits));
+    }
+
+    fn grad_of(a: f32, b: f32, c: f32, from_logits: bool, index: usize) -> f32 {
+        const predictions : [3]f32 = [a, b, c];
+        const targets : [3]f32 = [1.0, 0.0, 1.0];
+        var grads : [3]f32 = [9.0] ** 3;
+        gradient(&predictions, &targets, cfg(from_logits), &grads);
+        return grads[index];
+    }
+
+    fn batch_loss() -> f32 {
+        const predictions : [4]f32 = [0.8, 0.3, 0.9, 0.1];
+        const targets : [4]f32 = [1.0, 0.0, 1.0, 0.0];
+        return forward_batch(&predictions, 2, &targets, cfg(false));
+    }
+
+    fn valid_input() -> f32 {
+        return loss_of(0.8, 0.3, 0.9, false);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test sigmoid_basic_case
+        given input = 0.0
+        when result = sigmoid(input)
+        then @abs(result - 0.5) < 1e-6
+
+    test sigmoid_positive_input
+        given input = 1.0
+        when result = sigmoid(input)
+        then result > 0.5 and result < 1.0 and @abs(result - 0.7310586) < 0.000001
+
+    test sigmoid_negative_input
+        given input = -1.0
+        when result = sigmoid(input)
+        then result > 0.0 and result < 0.5 and @abs(result + sigmoid(1.0) - 1.0) < 0.000001
+
+    // -(ln 0.8 + ln 0.7 + ln 0.9) / 3 = 0.2283930
+    test forward_basic_case
+        given result = loss_of(0.8, 0.3, 0.9, false)
+        then result > 0.0 and @abs(result - 0.2283930) < 0.000001
+
+    // From logits (2, -1, 3) it is the same loss as from their sigmoids
+    test forward_from_logits_case
+        given result = loss_of(2.0, -1.0, 3.0, true)
+        when probs = loss_of(sigmoid(2.0), sigmoid(-1.0), sigmoid(3.0), false)
+        then result > 0.0 and @abs(result - probs) < 0.000001
+
+    // (-ln 0.8 - ln 0.7 - ln 0.9 - ln 0.9) / 4 = 0.1976349
+    test forward_batch_basic_case
+        given result = batch_loss()
+        then result > 0.0 and @abs(result - 0.1976349) < 0.000001
+
+    // t = 1 pulls p up (negative gradient), t = 0 pushes it down (positive)
+    test gradient_basic_case
+        given g0 = grad_of(0.8, 0.3, 0.9, false, 0)
+        when g1 = grad_of(0.8, 0.3, 0.9, false, 1)
+        then g0 < 0.0 and g1 > 0.0 and grad_of(0.8, 0.3, 0.9, false, 2) < 0.0 and @abs(g0 + 1.25) < 0.000001 and @abs(g1 - 1.0 / 0.7) < 0.000001
+
+    // From logits: sigmoid(z) - t, and it matches a finite difference of the loss
+    test gradient_from_logits_case
+        given g1 = grad_of(2.0, -1.0, 3.0, true, 1)
+        when slope = 3.0 * (loss_of(2.0, -1.0 + 0.001, 3.0, true) - loss_of(2.0, -1.0 - 0.001, 3.0, true)) / 0.002
+        then @abs(g1 - sigmoid(-1.0)) < 0.000001 and @abs(g1 - slope) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // targets[i] in {0, 1}: a perfect prediction costs (almost) nothing
+    invariant binary_ce_constraint_0
+        assert loss_of(1.0, 0.0, 1.0, false) < 0.000001
+
+    // 0 < epsilon << 1
+    invariant binary_ce_constraint_1
+        assert DEFAULT_EPSILON > 0.0 and DEFAULT_EPSILON < 0.001
+
+    // name: binary_ce -- positive for an imperfect prediction
+    invariant binary_ce_constraint_2
+        assert valid_input() > 0.0
+
+    // name: gradient -- zero where the logit already gives the target
+    invariant binary_ce_constraint_3
+        assert @abs(grad_of(30.0, -30.0, 30.0, true, 0)) < 0.000001
+
+    // "Bishop (2006) - Pattern Recognition and Machine Learning": the loss falls as p nears t
+    invariant binary_ce_constraint_4
+        assert loss_of(0.9, 0.1, 0.9, false) < loss_of(0.6, 0.4, 0.6, false)
+
+    // "Goodfellow et al. (2016) - Deep Learning": clipping keeps a certain wrong answer finite
+    invariant binary_ce_constraint_5
+        assert loss_of(0.0, 1.0, 0.0, false) < 20.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/dropout/card.png b/apps/website/public/learn/dropout/card.png new file mode 100644 index 0000000000000000000000000000000000000000..358769e5188d7869c9209c33adbc93a175a0d778 GIT binary patch literal 43890 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
7b_1c$AJ4r>+3sR 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 EFNk^l2mk;8 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/dropout/index.html b/apps/website/public/learn/dropout/index.html new file mode 100644 index 0000000000..23e11c34f5 --- /dev/null +++ b/apps/website/public/learn/dropout/index.html @@ -0,0 +1,208 @@ + + + + + + +Dropout: neural networks course, lesson 9 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Dropout

+

You will learn

Why switching units off while training helps, and why the survivors must be scaled.

+

While training, dropout switches off a share p of the units at random, so the rest cannot lean on any one of them. The units that survive must then be scaled, or the next layer would see the signal at another size in training than at inference. Inverted dropout scales them by 1 / (1 - p) while training: with p = 0.5, input 1, 2, 3, 4 becomes 2, 0, 6, 0, and inference is a plain pass. Classic dropout keeps 1, 0, 3, 0 and scales by 0.5 at inference instead. The spec dropout_layer.t27 uses a fixed mask, keep, drop, keep, drop, so the numbers are the same every time.

+

Try it

Compare the outputs of the four modes; then read the gradient of a dropped unit in training.

+

Open the interactive lesson →

+
Dropout: training a network with neurons switched off
Dropout: training a network with neurons switched off ↗
+

Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size.

+

specs/ml/layers/dropout_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Prevent co-adaptation of neurons | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the tests called `allocf32` and `allocbool`, which no spec declares, and
+// asserted `result != undefined`. Inference also scaled by (1 - p) even for
+// inverted dropout, which already scaled by 1 / (1 - p) in training, so the
+// expected activation shrank by (1 - p) between training and inference. Inference
+// is now the identity when scale_during_training is set.
+
+module Dropout;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_DROP_RATE : f32 = 0.5;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const DropoutConfig = struct {
+        p : f32,
+        inplace : bool,
+        scale_during_training : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) → void
+    fn forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) -> void {
+        const n = input.len;
+        var i : usize = 0;
+        while (i < n) {
+            if (training) {
+                if (mask[i]) {
+                    // Neuron is kept, scale during training if configured
+                    if (config.scale_during_training) {
+                        output[i] = input[i] * (1.0 / (1.0 - config.p));
+                    } else {
+                        output[i] = input[i];
+                    }
+                } else {
+                    // Neuron is dropped
+                    output[i] = 0.0;
+                }
+            } else {
+                if (config.scale_during_training) {
+                    // Inverted dropout already scaled in training: inference is the identity
+                    output[i] = input[i];
+                } else {
+                    // Classic dropout: scale by the keep probability at inference
+                    output[i] = input[i] * (1.0 - config.p);
+                }
+            }
+            i = i + 1;
+        }
+    }
+
+    // backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) → void
+    fn backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) -> void {
+        const n = grad_output.len;
+        var i : usize = 0;
+        while (i < n) {
+            if (mask[i]) {
+                // Gradient flows through kept neurons
+                if (config.scale_during_training) {
+                    grad_input[i] = grad_output[i] * (1.0 / (1.0 - config.p));
+                } else {
+                    grad_input[i] = grad_output[i];
+                }
+            } else {
+                // Gradient is zero for dropped neurons
+                grad_input[i] = 0.0;
+            }
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    fn cfg(scaled: bool) -> DropoutConfig {
+        return DropoutConfig{ .p = DEFAULT_DROP_RATE, .inplace = false, .scale_during_training = scaled };
+    }
+
+    // forward on input (1, 2, 3, 4) with mask (keep, drop, keep, drop)
+    fn forward_at(training: bool, scaled: bool, index: usize) -> f32 {
+        const input : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var output : [4]f32 = [9.0] ** 4;
+        var mask : [4]bool = [true, false, true, false];
+        forward(&input, &output, &mask, training, cfg(scaled));
+        return output[index];
+    }
+
+    fn backward_at(scaled: bool, index: usize) -> f32 {
+        const grad_output : [4]f32 = [1.0, 1.0, 1.0, 1.0];
+        const mask : [4]bool = [true, false, true, false];
+        var grad_input : [4]f32 = [9.0] ** 4;
+        backward(&grad_output, &mask, &grad_input, cfg(scaled));
+        return grad_input[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // p = 0.5, inverted: kept units are doubled, dropped ones are 0
+    test forward_basic_case
+        given kept = forward_at(true, true, 2)
+        when dropped = forward_at(true, true, 1)
+        then kept == 6.0 and dropped == 0.0 and forward_at(true, true, 0) == 2.0
+
+    // The expected activation is the same in training and inference
+    test forward_inference_keeps_the_expectation
+        given inverted = forward_at(false, true, 2)
+        when classic = forward_at(false, false, 2)
+        then inverted == 3.0 and classic == 1.5 and forward_at(true, false, 2) == 3.0
+
+    // The gradient flows only through kept units, with the same scale
+    test backward_basic_case
+        given kept = backward_at(true, 0)
+        when dropped = backward_at(true, 3)
+        then kept == 2.0 and dropped == 0.0 and backward_at(false, 2) == 1.0
+
+    invariant dropout_rate_is_a_probability
+        assert DEFAULT_DROP_RATE >= 0.0 and DEFAULT_DROP_RATE < 1.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/elu/card.png b/apps/website/public/learn/elu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..a75e49ae4e1937803dc57471c9c86b23ed320ecf GIT binary patch literal 51367 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�u{JAJHxC~GaQ>D;;DNk zWTT#Q3zz_b%-M4MS%raD{KZzXwW^`vQXfr_ifI@ei)G|)&-fw#77G8mAw=B&v!>?$ zdMt=q#QjSn7O>BS-_#YW3Le37->RyPYO0B!-`^bZCXd_jPR-5v^u_!?}L?8 zRJ>xyc;z@!G^M$|p?j3@C^k;X_>5yUG&bH{wm*#Y_rv&bcMJH>7Tw0Qb##^kZw@R2 zH@8xZi_KDmZPddfrE4kFx5DFv-AE>(P*9;1HHlcz^%iNbw1`8nM$)tl`4r7qi_h8V z*%>q3L&RA{MMY5&Q(H{~P{}zt?!wp9;LidcVM=91^KSw`(o$fB zOqDe+vghUHMaN)bVk)Yr?86N6)USX%&$V<4#H;yOws@8$>cTTJvQjM;h+595`w);- zv9PgAVS>)9Z=k_o;zFLpiJ$i(vL}{j+aoyv7jxrzZ_}vXUVE;z1*kZ|HKx~NMGt4| z>}GPMf`JX#jnP`TU60~y@;d%p_DySFn~7MXG!c%P%xQcNhvaxN|9PAm9QYa5XA7i7 z$-Z}_06~;f&+Bsk{UtKetjY2A>O>1;4;IftA!EZODtg0m><)DuM-CG(0!g^cRs za=ymcG_i*d@iy}S1_nlss8?(?-#j;)M~yXpUh8ESz9b*{5`0K{;Tu-K@O0x=vOZAa zV9qM<-;=o=&@nPD^!v<@XO!Hz?__xme&9jYc-x@+pHNvME8=jZ1Zxzj1efx;j933^?vaaY{N z#L+nek2^3ndSlGltOgUAm6O>_*&ulU`wXYK->Ym-m52*O0^9XIn3OrPKIp_&oh&() zm}{m#440zG%ZU4<%~T+{uq(yD60Bd>-Qy9iTkS!oLXNX zo%_9_{+lWP1Sw5tf8WRHEeXXYC2!SKxKy9WrCEx3DJEv{zPZQTNd6I}QPU ze(;pLi%XvQK(uU@WY9hEF9P1*UL{2MDmXYC09kjwJ#f7nb9*-x_OtIduraDR5+Lo@ zZo2|g=@5YcM@No_L^DWQyN-v4N6_sFM!B0?WHKM)nE2%)Yh_EP`@|!{`GgD1i#I@V;ukNd0*fZ_$ocw*WBqLcMzch{ zrpvSsZaTc2onMG~JImK6pKsK*n=+5|7Q{*D>FE5i;T-3K1G98z^=!qs+)m3amn%Uz z68Au|AGeC5k(6+luU%^Pg3{=u<07Gdh*Anr-&_Kk=Gm0(7?AZ!_LPy&j9a|9p(NXg zd_|(I8-dLn4bhCqNJRJ_jTy}eYa#zDE`CuFIrt${v-$09Dpr85sSmtEt^_?~1p!B_UV}J|-!2)h zCVst{V2B%1D>N`L(A0bluE}qikI}M`^6~MhWoL3aQwztXxB#mD z4vy^{4W9(~Fd%G8v=JkME5~Z`(J!Rz;*zt-)fgmXDbn>?r@q*?LoKbWGGNmY8uiy+ zuejgbyn}T4pY)JAwVwaU7Wcb?0NNt&4`bc!i;oq#l;;SjT1sN#c%bStp!CP`P*Xke zf#rq6QilLdr_}y}`1((U;ZPsCuI`NJA<%QKY|Ez^D^gCGl%kv`xdsEp9T1h1Gif|) zhF(ju5hvj^fvF-MEK~qf{5f`I3RG|T6>?_Khl*H9m_VVw{wx_Fnz;`SWML!^ZIZQ6L1aUoqbOo_s_csp$UXELq<% zZ+!=NHC`)0+ro_Y$oZ*CGR?+zxi|@fbx9x zMq%%hr4dj8KdkShWl!Sw0QyzAs~u3w6ax0Sm=nWR78Vmi%pWG_a~EaJfv-K}9*Uji z=H`M64*j=HCy zpg)=3mQqvJd$rMOBaXI}dy_Bovcf%SZR2@R45d0E+FZ0A6$GmzUaMio1bSNI7tTMs z`!&vq8ldTUFki&_YI5L zYcgtvF$Y8vjsoRI9?cVZ2tDC1dowBcEs)WsiH}i>qHqAbm@jh)2sm|cMQLe7TNr{_ zNt8GQX1pX!tW^SOkWJVQlC=57Of&h6p2cQzirILgeROp6_IF|wQvi6gKo|Cok%};% zOr41s$r@rtLB&2PIgk?=VYZd=iDUFZkV&@sbzsm*xR#s7&%ApwqzK~h(xTIA5 z)r^{6&`_o5{Ec}5YH8x3dza?z4IrItpqb)+$w8qKvU`!}#ZyXiam6=hW0KGgCEqs- z=>m`F-vY6M1L!FP^ueuu{L|as3v~uEQBO9itfJTHx2$^Q$@hQ4!ooBHa#_vIoIYD2 z-Q|_CsSLSgH3c8`2k$!<78VdFTCQ-|4=t9SaT-ISoT6Ub6-9f<43maRUHaZ~dCXpkW-* zSK2dxc!kVPr~attJ=M#Pd|pTDf%XK27d)TmM0EFk!WuTD@a$WlwzXto$lGthk7+~6 zmcZ;HPi5D_Ysh-If=>)KRdOV!v7WcWo3ztv`YCGqAUnps+6;<#~p)|hcx%M#= z5BODnP^rOK3S2cyM7D2c!|vHPY3uASpEPUsU)iim{Bn-|MsV`Ap{ z6z9{&BebE~$i26`DkHRd&gA%a zTU+``o#=pmPl(RDZ;TJgd$RE^ZWUQaHg6__S(|2(+j7d~b%4 zjxO~@uCj}4`_nmj_bJx+Yw<;Q@(7Ue+1s8F!Da8RZnB9i2EL(q1-fDk@0){qP>b?J z3V9#S$GMU~+0uwk95fOU8R>H?-{XV&6%CR6H_~Y_g9c4@Pnj>o00n?^86I(;cm@ua zZ@2vGZa!W2UjhbWlGU9!o_a5ykc7gfR;xVU6vj^ehK>-N71@bdhik3MBmtJmBk+zm z1FFfS74toKw9qGaY!bp`v>W>hT(vp&2|~(zdz_be#2+38RP@|$$1aJzZ-2_a)yOR9 z)+3cEQdYUjj3LC`mZRmJ6Z zc@$&hzKy3cBzMe(`i*;tu#<$tD^#(~0JYExe*}0i!S9$MfXWtFDp$BsmBDduYPy=w zg$qdq#e38l7eq!z0xV*2X-Skk7dlc_nV7&V?%c*jwsjvVEozdI8WW znDs}F^0n_)>t=dk`s~G=S9!gxb#T#Eq33UQ9)}0{XLr@2(}jJ%fzy009M2b}st(XC zYKq(I&82wvAbYPr_MjZ}Mp;P-@Y`iu$H8!{k4=huM%*uGM}iMYmij!-Ot`onL?joQ zxG8R*@Vlk{a<|}H3ceuXuV!&i_|uxNpLroTCEzU^B!=!(ho6t!tGZKTYBy*a0cA{D zC!&3{dpbjK0nQ5JI}=^oNBnLVrYbdzQEfH_X1XO+@J%dfBJQLi<+rNMTnFwe4JW-6 zaAPQyrKj&BeMr|hEoSd8k9lM3o1f)4Fb-Uv$XF_bB~5lQ#KKp{2TA(jF~S9qx*1Mw za6~0O%18D$FZT;X%KOup*j~VDjR&*wLb7ytM9WPtP8;3C2Vnth2wVz*VFZf*GViCO z$X<8sWf}O`u<5Yk(?6j0A({daP;@cx3o4zXktBO$Rg`enU3vxg=a^>yYaRL&i z;{+iYi}W8o>693>#?L_#5)$6t-lmSKH^FKvI|m1qiWxoT>1`l}#OXf^?_>i4THzsL zfw$hhg{samt&{)50(41pgh4z0gR{jOky z@K8KFJivF6g3MzK&3YY|H+hgh^u+V`{M0R#I5XD1))*X*ob`&XpGn&e6 zeto({)p`Rfh|`-3Rjid(nbLp!_%Tq{IEYBGBraynqZMz_{E9b1va*(-YLX7?0v`bY zLTs*q-$TNZ-qX{wnE{=)r3x;Bs2mm^(m2erXam3_wx9w^Ow$N7*22m$NyR zC}4;uGmUOL&q+u;5Qp*f$}c{~8n$?!#0V~@^4mRMA!P#mpd{F|s%K$dphdsrRl}g9BLv6yv#Rb%@$Q{_KDIbbO zM}jg_VR!?ukGh~eKyd$RJM0HEwkM$1(_g$~XFoU!dT5@A!d&q`8&N&-RM*kzO$E2> zRhe{D7&ZqY;gAa_@#Ej9Q%J$P6V(lM!A0Qc0)rJz-;G|sdSzWXTWbU59TS6M+%O%v z_hk#YtOGT>-Et)T!fArX(_J1b%cz3D)7QaPTKe$;m#F8y^~0aPC~Y%AjR%DRd^6x~ zT!(_<40=g$L0sn4-P_A!DANb>sHgM>7G@lHZ9z&(O4J1~23BIMNEJX%XLCq4G&O0Q zgwI=Lc``z$rex;2VEUK9`T%b};PtiqZBK6!tFFfTQ<{e>4D(+JjB57)qylUKH#bgD zu%Rt0EIotRi#b8;X8&jO^fhv?(%j5U1!r|*`zE%TUY6sG_-X4)BGNz#88Fv`oAI z0>E5CJgCQ13-3HPx@@S|vQOVj++B5$>tAU7%fWnDE=GaHA&r_L+U;;r*!F{FX7RhB zcg$EOfJZCdXlic0!NQw%uvU8^?#t&u+=~PFspk(LFN)LvbNo%7np<4#p|#}u_ZuK* z$;DFsV<0%SQlbYMMat-SlnN`A7dBtz(;_wc+8^$misKYPpduLu-_&p+Eec_v)dBD- z(F2>XdZ(2(!1eO9e!1XFH-n^5GCEu56jFu78l*Pr1CahrPN=E{k}uLH*}-$Kpwm!3 z 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/elu/index.html b/apps/website/public/learn/elu/index.html new file mode 100644 index 0000000000..600886bea4 --- /dev/null +++ b/apps/website/public/learn/elu/index.html @@ -0,0 +1,197 @@ + + + + + + +ELU: a floor, not a cliff: neural networks course, lesson 6 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

ELU: a floor, not a cliff

+

You will learn

How ELU keeps a soft negative side with a floor at -alpha, and why its slope never quite dies.

+

ELU keeps the positive side of ReLU and replaces the cliff on the negative side with alpha (e^x - 1), a curve that flattens toward -alpha. With alpha 1, x = -3 gives -0.9502, already near the floor of -1, and the slope there is 0.0498: small, but not 0, so the unit can still move. Because the negative outputs are not thrown away, a layer's outputs average closer to 0. The spec elu_activation.t27 computes the curve, the slope and the floor, and its own batch at -1, 0 and 2: -0.632, 0 and 2.

+

Try it

Set alpha to 0.5 and read the floor; then find how far left x must go before the slope is under 0.01.

+

Open the interactive lesson →

+
ELU: a negative side with a floor
ELU: a negative side with a floor ↗
+

Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies.

+

specs/ml/activation/elu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative | φ² + 1/φ² = 3 | TRINITY
+// #8980: `math::exp` named a module this spec never imports, forward_batch grew
+// an array with `+`, and every test called a two-argument function with one
+// argument and asserted `result != undefined`. Now each test checks a value.
+
+module Elu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_ALPHA : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const ELUConfig = struct {
+        alpha : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(x, alpha) = x for x > 0, alpha * (exp(x) - 1) otherwise
+    fn forward(x: f32, alpha: f32) -> f32 {
+        if (x > 0.0) {
+            return x;
+        }
+        return alpha * (exp(x) - 1.0);
+    }
+
+    // forward_batch: output[i] = forward(input[i], alpha)
+    fn forward_batch(input: []const f32, alpha: f32, output: []f32) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = forward(input[i], alpha);
+            i = i + 1;
+        }
+    }
+
+    // derivative(x, alpha) = 1 for x > 0, alpha * exp(x) otherwise
+    fn derivative(x: f32, alpha: f32) -> f32 {
+        if (x > 0.0) {
+            return 1.0;
+        }
+        return alpha * exp(x);
+    }
+
+    // The inputs the tests and invariants share: one negative, zero, one positive.
+    fn negative_input() -> f32 {
+        return -1.0;
+    }
+
+    fn valid_input() -> f32 {
+        return 2.0;
+    }
+
+    fn batch_at(index: usize) -> f32 {
+        const input : [3]f32 = [-1.0, 0.0, 2.0];
+        var output : [3]f32 = [0.0] ** 3;
+        forward_batch(&input, DEFAULT_ALPHA, &output);
+        return output[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // ELU(-1) = exp(-1) - 1 = -0.6321206; ELU(2) = 2
+    test "forward_basic_case"
+        given input = negative_input()
+        when result = forward(input, DEFAULT_ALPHA)
+        then @abs(result - (-0.6321206)) < 0.000001 and forward(valid_input(), DEFAULT_ALPHA) == 2.0
+
+    // alpha scales only the negative side, and ELU(x) never goes below -alpha (in f32
+    // ELU(-20) rounds to exactly -alpha)
+    test "forward_alpha_scales_negative_side"
+        given input = negative_input()
+        when result = forward(input, 0.5)
+        then @abs(result - 0.5 * forward(input, 1.0)) < 0.000001 and forward(-20.0, 0.5) >= -0.5
+
+    test "forward_batch_basic_case"
+        given input = negative_input()
+        when result = batch_at(0)
+        then result == forward(input, DEFAULT_ALPHA) and batch_at(1) == 0.0 and batch_at(2) == 2.0
+
+    // ELU'(-1) = exp(-1) = 0.3678794; ELU'(2) = 1
+    test "derivative_basic_case"
+        given input = negative_input()
+        when result = derivative(input, DEFAULT_ALPHA)
+        then @abs(result - 0.3678794) < 0.000001 and derivative(valid_input(), DEFAULT_ALPHA) == 1.0
+
+    test "derivative_matches_finite_difference"
+        given slope = (forward(-1.0 + 0.001, DEFAULT_ALPHA) - forward(-1.0 - 0.001, DEFAULT_ALPHA)) / 0.002
+        when result = derivative(-1.0, DEFAULT_ALPHA)
+        then @abs(result - slope) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    invariant elu_constraint_0
+        assert DEFAULT_ALPHA > 0.0
+
+    // name: elu_formula -- identity on the positive side
+    invariant elu_constraint_1
+        assert forward(valid_input(), DEFAULT_ALPHA) == valid_input()
+
+    // name: derivative -- 1 on the positive side
+    invariant elu_constraint_2
+        assert derivative(valid_input(), DEFAULT_ALPHA) == 1.0
+
+    // "Clevert et al. (2016) - Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)":
+    // ELU is continuous at 0
+    invariant elu_constraint_3
+        assert forward(0.0, DEFAULT_ALPHA) == 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/embeddings/card.png b/apps/website/public/learn/embeddings/card.png new file mode 100644 index 0000000000000000000000000000000000000000..17efd774bc6a62af7db5941328bf31e1ce5cd1a8 GIT binary patch literal 45216 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%0DJWqkR-ZhAWNay@3rz)zEr47BpR=kXvTxo&_ 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 + + + + + +Embeddings: neural networks course, lesson 8 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Embeddings

+

You will learn

How a token becomes a row of numbers, and why learning changes only the rows that were read.

+

A network cannot multiply a word, so each token is an index into a table with one row of numbers per token, and looking a token up copies its row. In the spec the table has 4 tokens of width 2 and row v holds (10 v, 10 v + 1), so token 2 reads (20, 21). Learning sends the gradient back only to the rows that were read, and a token read twice collects both: gradient rows (1, 2) and (3, 4) on token 2 add up to (4, 6). The spec embedding_layer.t27 computes the lookup and the gradient.

+

Try it

Read token 2 twice and then tokens 1 and 3; count the rows whose gradient is not 0 each time.

+

Open the interactive lesson →

+
Embeddings: how a word becomes a row of numbers
Embeddings: how a word becomes a row of numbers ↗
+

Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both.

+

specs/ml/layers/embedding_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Embeddings are learned parameters | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward only asserted its arguments and wrote nothing, the tests called
+// undeclared `test_input_forward` / `test_input_init` and asserted
+// `result != undefined`, and the invariants asserted `true`. forward now looks each
+// token's row up in W (vocab_size x d_model, row-major), backward adds each
+// gradient row back into the row it came from, and init fills W deterministically.
+
+module Embedding;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_D_MODEL : u32 = 64;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const EmbeddingConfig = struct {
+        vocab_size : u32,
+        d_model : u32,
+    };
+
+    pub const EmbeddingWeights = struct {
+        W : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // embeddings[t * d + j] = W[token_ids[t] * d + j]: one row of W per token
+    fn forward(token_ids: []const u32, weights: EmbeddingWeights, embeddings: []f32, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        var t : usize = 0;
+        while (t < token_ids.len) {
+            const row : usize = token_ids[t];
+            var j : usize = 0;
+            while (j < d) {
+                embeddings[t * d + j] = weights.W[row * d + j];
+                j = j + 1;
+            }
+            t = t + 1;
+        }
+    }
+
+    // grad_W[token_ids[t]] += grad_embeddings[t]: a token seen twice collects both rows
+    fn backward(token_ids: []const u32, grad_embeddings: []const f32, grad_W: []f32, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        var t : usize = 0;
+        while (t < token_ids.len) {
+            const row : usize = token_ids[t];
+            var j : usize = 0;
+            while (j < d) {
+                grad_W[row * d + j] = grad_W[row * d + j] + grad_embeddings[t * d + j];
+                j = j + 1;
+            }
+            t = t + 1;
+        }
+    }
+
+    // Deterministic init in [-0.5, 0.5) / sqrt(d_model): a fixed hash of (row, column), so
+    // two runs start from the same weights
+    fn init(weights: EmbeddingWeights, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d)));
+        var k : usize = 0;
+        while (k < config.vocab_size * d) {
+            const h : u32 = @as(u32, @intCast((k * 2654435761) % 1000));
+            weights.W[k] = (@as(f32, @floatFromInt(h)) / 1000.0 - 0.5) * scale;
+            k = k + 1;
+        }
+    }
+
+    // vocab 4, d_model 2, W row v = (10 v, 10 v + 1)
+    fn cfg() -> EmbeddingConfig {
+        return EmbeddingConfig{ .vocab_size = 4, .d_model = 2 };
+    }
+
+    fn lookup_at(a: u32, b: u32, index: usize) -> f32 {
+        var w : [8]f32 = [0.0, 1.0, 10.0, 11.0, 20.0, 21.0, 30.0, 31.0];
+        const ids : [2]u32 = [a, b];
+        var out : [4]f32 = [-1.0] ** 4;
+        forward(&ids, EmbeddingWeights{ .W = &w }, &out, cfg());
+        return out[index];
+    }
+
+    // grad_W[index] after backward of ids (a, b) with gradient rows (1, 2) and (3, 4)
+    fn grad_at(a: u32, b: u32, index: usize) -> f32 {
+        const ids : [2]u32 = [a, b];
+        const grads : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var grad_w : [8]f32 = [0.0] ** 8;
+        backward(&ids, &grads, &grad_w, cfg());
+        return grad_w[index];
+    }
+
+    fn init_at(index: usize) -> f32 {
+        var w : [8]f32 = [9.0] ** 8;
+        init(EmbeddingWeights{ .W = &w }, cfg());
+        return w[index];
+    }
+
+    fn valid_input() -> u32 {
+        return cfg().vocab_size * cfg().d_model;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // ids (2, 0): rows (20, 21) then (0, 1)
+    test forward_basic_case
+        given first = lookup_at(2, 0, 0)
+        when last = lookup_at(2, 0, 3)
+        then first == 20.0 and lookup_at(2, 0, 1) == 21.0 and lookup_at(2, 0, 2) == 0.0 and last == 1.0
+
+    // Every weight is written, inside [-0.5, 0.5) / sqrt(2), and init is reproducible
+    test init_basic_case
+        given first = init_at(0)
+        when last = init_at(7)
+        then first != 9.0 and last != 9.0 and @abs(first) <= 0.36 and @abs(last) <= 0.36 and init_at(5) == init_at(5) and init_at(1) != init_at(2)
+
+    // A token seen twice collects both gradient rows; an unseen row stays 0
+    test backward_accumulates_repeated_tokens
+        given row1 = grad_at(1, 1, 2)
+        when unseen = grad_at(1, 1, 0)
+        then row1 == 4.0 and grad_at(1, 1, 3) == 6.0 and unseen == 0.0 and grad_at(1, 3, 6) == 3.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // vocab_size > 0
+    invariant embedding_constraint_0
+        assert cfg().vocab_size > 0
+
+    // d_model > 0
+    invariant embedding_constraint_1
+        assert cfg().d_model > 0 and DEFAULT_D_MODEL > 0
+
+    // W.size() == vocab_size * d_model
+    invariant embedding_constraint_2
+        assert valid_input() == 8
+
+    // token_ids must be in [0, vocab_size): the last id reads the last row
+    invariant embedding_constraint_3
+        assert lookup_at(3, 3, 1) == 31.0
+
+    // "Embedding dimension affects model capacity": each token gets d_model numbers
+    invariant embedding_constraint_4
+        assert lookup_at(1, 2, 1) == 11.0 and lookup_at(1, 2, 2) == 20.0
+
+    // "Larger vocab requires larger d_model": the init scale shrinks as 1 / sqrt(d_model)
+    invariant embedding_constraint_5
+        assert 1.0 / sqrt(@as(f32, 64.0)) < 1.0 / sqrt(@as(f32, 2.0))
+
+    // "Pre-trained embeddings transfer well": forward is a pure lookup, so loaded rows come out unchanged
+    invariant embedding_constraint_6
+        assert lookup_at(0, 1, 0) == 0.0 and lookup_at(0, 1, 2) == 10.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/gelu/card.png b/apps/website/public/learn/gelu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..42a18dad0ac859072f6fb195212cb88fb4eab7a9 GIT binary patch literal 53620 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

J=oQ&wINcx?#Q(m{BR0x9oXGjrEp@cQN}1W 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 F{~sIo9?Jj# literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/gelu/index.html b/apps/website/public/learn/gelu/index.html new file mode 100644 index 0000000000..b4c092d4f6 --- /dev/null +++ b/apps/website/public/learn/gelu/index.html @@ -0,0 +1,242 @@ + + + + + + +GELU: a dip below zero: neural networks course, lesson 4 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

GELU: a dip below zero

+

You will learn

What GELU computes, why it dips below zero, and how close its tanh shortcut comes.

+

GELU weighs x by the chance that a standard normal draw is below it: GELU(x) = x Phi(x). A large positive input passes, a large negative one vanishes, and in between the curve dips to about -0.17 near x = -0.75 before it rises. BERT and GPT use it in their feed-forward layers. The exact form needs erf, which the spec computes with the Abramowitz-Stegun fit, good to 1.5e-7, and it also computes the tanh shortcut: at -0.75 they give -0.16997 and -0.17004. The spec gelu_activation.t27 computes both curves and their slopes.

+

Try it

Find the lowest point of the curve by its slope; then compare the exact and the tanh form at -3.

+

Open the interactive lesson →

+
GELU: why transformers bend a little below zero
GELU: why transformers bend a little below zero ↗
+

Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form.

+

specs/ml/activation/gelu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Based on cumulative distribution function | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: Zig has neither `@tanh` nor `@erf`, so this never compiled. erf is now
+// a function of this spec (Abramowitz-Stegun 7.1.26, |error| < 1.5e-7), and the
+// exact derivative divides the normal density by sqrt(2 pi), not sqrt(2) (the
+// slip was invisible at x = 0, the only point the tests checked).
+
+module Gelu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const SQRT_2_OVER_PI : f32 = 0.7978845608;
+    const SQRT_PI_OVER_2 : f32 = 1.2533141373;
+    const SQRT_2 : f32 = 1.4142135624;
+    const SQRT_2_PI : f32 = 2.5066282746;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const GELUConfig = struct {
+        approximate : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // erf(x), Abramowitz-Stegun 7.1.26: max absolute error 1.5e-7
+    fn erf(x: f32) -> f32 {
+        if (x < 0.0) {
+            return -erf(-x);
+        }
+        const t = 1.0 / (1.0 + 0.3275911 * x);
+        const poly = t * (0.254829592 + t * (-0.284496736 + t * (1.421413741 + t * (-1.453152027 + t * 1.061405429))));
+        return 1.0 - poly * exp(-x * x);
+    }
+
+    // One element. approximate: 0.5 x (1 + tanh(sqrt(2/pi) (x + 0.044715 x^3)));
+    // exact: 0.5 x (1 + erf(x / sqrt(2))) = x Phi(x)
+    fn gelu_one(x: f32, approximate: bool) -> f32 {
+        if (approximate) {
+            const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x);
+            return 0.5 * x * (1.0 + tanh(inner));
+        }
+        return 0.5 * x * (1.0 + erf(x / SQRT_2));
+    }
+
+    // d/dx of gelu_one
+    fn gelu_grad_one(x: f32, approximate: bool) -> f32 {
+        if (approximate) {
+            const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x);
+            const tanh_val = tanh(inner);
+            const sech_sq = 1.0 - tanh_val * tanh_val;
+            return 0.5 * (1.0 + tanh_val) + 0.5 * x * sech_sq * SQRT_2_OVER_PI * (1.0 + 3.0 * 0.044715 * x * x);
+        }
+        // Phi(x) + x phi(x), phi(x) = exp(-x^2 / 2) / sqrt(2 pi)
+        const cdf = 0.5 * (1.0 + erf(x / SQRT_2));
+        const pdf = exp(-0.5 * x * x) / SQRT_2_PI;
+        return cdf + x * pdf;
+    }
+
+    fn forward(input: []const f32, output: []f32, config: GELUConfig) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = gelu_one(input[i], config.approximate);
+            i = i + 1;
+        }
+    }
+
+    fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: GELUConfig) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            grad_input[i] = grad_output[i] * gelu_grad_one(input[i], config.approximate);
+            i = i + 1;
+        }
+    }
+
+    // forward / backward over a one-element slice, for the tests
+    fn forward_at(x: f32, approximate: bool) -> f32 {
+        const input : [1]f32 = [x];
+        var output : [1]f32 = [0.0];
+        forward(&input, &output, GELUConfig{ .approximate = approximate });
+        return output[0];
+    }
+
+    fn backward_at(x: f32, approximate: bool) -> f32 {
+        const grad_output : [1]f32 = [1.0];
+        const input : [1]f32 = [x];
+        var grad_input : [1]f32 = [0.0];
+        backward(&grad_output, &input, &grad_input, GELUConfig{ .approximate = approximate });
+        return grad_input[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // The product goes through a function so the check runs, not only folds at compile time.
+    fn product_of(a: f32, b: f32) -> f32 {
+        return a * b;
+    }
+
+    fn config_of(approximate: bool) -> GELUConfig {
+        return GELUConfig{ .approximate = approximate };
+    }
+
+    test gelu_sqrt_constants_are_reciprocals
+        given product = product_of(SQRT_2_OVER_PI, SQRT_PI_OVER_2)
+        then @abs(product - 1.0) < 0.0000005
+
+    test gelu_sqrt_2_over_pi_squares_to_2_over_pi
+        given squared = product_of(SQRT_2_OVER_PI, SQRT_2_OVER_PI)
+        then @abs(squared - 0.63661977) < 0.0000003
+
+    test gelu_config_records_the_approximation_choice
+        given exact = config_of(false)
+        when approx = config_of(true)
+        then !exact.approximate and approx.approximate
+
+    // erf(0) = 0, erf(1) = 0.8427008, erf(-1) = -erf(1)
+    test gelu_erf_known_values
+        given at_one = erf(1.0)
+        when at_zero = erf(0.0)
+        then @abs(at_zero) < 0.0000002 and @abs(at_one - 0.8427008) < 0.0000003 and erf(-1.0) == -at_one
+
+    test gelu_forward_zero_input
+        given exact = forward_at(0.0, false)
+        when approx = forward_at(0.0, true)
+        then exact == 0.0 and approx == 0.0
+
+    test gelu_backward_zero_input_derivative
+        given exact = backward_at(0.0, false)
+        when approx = backward_at(0.0, true)
+        then @abs(exact - 0.5) < 0.0000002 and approx == 0.5
+
+    test gelu_forward_monotonic_positive_tail
+        given small = forward_at(1.0, true)
+        when large = forward_at(2.0, true)
+        then small < large
+
+    // With the cubic term, approximate GELU(1) = 0.8411920; exact GELU(1) = Phi(1) = 0.8413447.
+    // Without it, 0.5 (1 + tanh(0.7978846)) = 0.8296438 -- so this pins the term.
+    test gelu_tanh_cubic_coefficient
+        given approx = forward_at(1.0, true)
+        when exact = forward_at(1.0, false)
+        then @abs(approx - 0.8411920) < 0.000001 and @abs(exact - 0.8413447) < 0.000001
+
+    test gelu_backward_exact_derivative_at_zero
+        given result = backward_at(0.0, false)
+        then @abs(result - 0.5) < 0.0000002
+
+    test gelu_forward_approx_derivative_at_zero
+        given result = backward_at(0.0, true)
+        then result == 0.5
+
+    // The derivative at x = 1 is where the old sqrt(2) slip showed: 1.0833155 exact
+    test gelu_backward_matches_finite_difference
+        given exact_slope = (forward_at(1.001, false) - forward_at(0.999, false)) / 0.002
+        when approx_slope = (forward_at(1.001, true) - forward_at(0.999, true)) / 0.002
+        then @abs(backward_at(1.0, false) - exact_slope) < 0.002 and @abs(backward_at(1.0, true) - approx_slope) < 0.002 and @abs(backward_at(1.0, false) - 1.0833155) < 0.000002
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/gradient-descent/card.png b/apps/website/public/learn/gradient-descent/card.png new file mode 100644 index 0000000000000000000000000000000000000000..5b76aac416b211f0aac24d4416890bd705f136df GIT binary patch literal 54133 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�We~i8} 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/gradient-descent/index.html b/apps/website/public/learn/gradient-descent/index.html new file mode 100644 index 0000000000..e5d49c2786 --- /dev/null +++ b/apps/website/public/learn/gradient-descent/index.html @@ -0,0 +1,239 @@ + + + + + + +Gradient descent: neural networks course, lesson 16 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Gradient descent

+

You will learn

How gradient descent walks down a loss, what momentum adds, and why too large a rate never settles.

+

Training is walking downhill on the loss. Gradient descent moves a weight by -lr times its gradient each step; in the spec the loss is (x - 3)^2 from x = 0, and lr 0.1 reaches 2.99996 in 50 steps. Momentum adds a share of the last move, which speeds up a long slope and overshoots a sharp bottom: at 0.9 the weight shoots past 3 to about 5.13 and rings down to 3.09 after 50 steps. Nesterov takes the gradient one step ahead and swings less, to about 4.25. Too large a rate never settles: at lr 1 the weight bounces between 0 and 6 for good. The spec sgd.t27 computes every step.

+

Try it

Find the largest learning rate that still settles without momentum; then add momentum 0.9 and count the swings.

+

Open the interactive lesson →

+
Gradient descent: how a network walks downhill
Gradient descent: how a network walks downhill ↗
+

Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever.

+

specs/ml/optimizer/sgd.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Nesterov accelerated gradient (NAG) | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: init called `new f32[n]`; update read undeclared locals; dampening and
+// nesterov were ignored; and weight decay was ADDED to the parameter
+// (`- v + wd * p`), which grows the weights it should shrink. update is now
+// PyTorch's SGD: g = grad + wd p; v = mu v + (1 - dampening) g;
+// step = g + mu v (Nesterov) or v; p = p - lr step.
+
+module Sgd;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_LR : f32 = 0.01;
+    const DEFAULT_MOMENTUM : f32 = 0.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SGDConfig = struct {
+        learning_rate : f32,
+        momentum : f32,
+        weight_decay : f32,
+        dampening : f32,
+        nesterov : bool,
+    };
+
+    pub const SGDState = struct {
+        velocity : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // init: the first param_count velocities start at zero (the caller owns the buffer)
+    fn init(state: SGDState, param_count: u32) -> void {
+        var i : usize = 0;
+        while (i < param_count) {
+            state.velocity[i] = 0.0;
+            i = i + 1;
+        }
+    }
+
+    fn update(params: []f32, grads: []const f32, state: SGDState, config: SGDConfig) -> void {
+        var i : usize = 0;
+        while (i < params.len) {
+            const g = grads[i] + config.weight_decay * params[i];
+            var step = g;
+            if (config.momentum > 0.0) {
+                state.velocity[i] = config.momentum * state.velocity[i] + (1.0 - config.dampening) * g;
+                if (config.nesterov) {
+                    step = g + config.momentum * state.velocity[i];
+                } else {
+                    step = state.velocity[i];
+                }
+            }
+            params[i] = params[i] - config.learning_rate * step;
+            i = i + 1;
+        }
+    }
+
+    fn cfg(lr: f32, momentum: f32, wd: f32, nesterov: bool) -> SGDConfig {
+        return SGDConfig{ .learning_rate = lr, .momentum = momentum, .weight_decay = wd, .dampening = 0.0, .nesterov = nesterov };
+    }
+
+    // Minimise f(x) = (x - 3)^2 (gradient 2 (x - 3)) from x = 0 for `steps` steps
+    fn descend(lr: f32, momentum: f32, nesterov: bool, steps: u32) -> f32 {
+        var params : [1]f32 = [0.0];
+        var velocity : [1]f32 = [5.0];
+        const state = SGDState{ .velocity = &velocity };
+        init(state, 1);
+        var n : u32 = 0;
+        while (n < steps) {
+            const grads : [1]f32 = [2.0 * (params[0] - 3.0)];
+            update(&params, &grads, state, cfg(lr, momentum, 0.0, nesterov));
+            n = n + 1;
+        }
+        return params[0];
+    }
+
+    fn init_zeroes(index: usize) -> f32 {
+        var velocity : [3]f32 = [7.0, 7.0, 7.0];
+        init(SGDState{ .velocity = &velocity }, 3);
+        return velocity[index];
+    }
+
+    // One step on params (1, 2), grads (0.1, 0.2), momentum 0.9, weight decay 0.001
+    fn one_step(index: usize) -> f32 {
+        var params : [2]f32 = [1.0, 2.0];
+        const grads : [2]f32 = [0.1, 0.2];
+        var velocity : [2]f32 = [0.0, 0.0];
+        update(&params, &grads, SGDState{ .velocity = &velocity }, cfg(0.01, 0.9, 0.001, false));
+        return params[index];
+    }
+
+    // A step with zero gradient and weight decay shrinks the weight toward 0
+    fn decay_step() -> f32 {
+        var params : [1]f32 = [2.0];
+        const grads : [1]f32 = [0.0];
+        var velocity : [1]f32 = [0.0];
+        update(&params, &grads, SGDState{ .velocity = &velocity }, cfg(0.1, 0.0, 0.5, false));
+        return params[0];
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_LR;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test "init_basic_case"
+        given first = init_zeroes(0)
+        when last = init_zeroes(2)
+        then first == 0.0 and last == 0.0
+
+    // v = g + wd p (momentum starts at 0): p0 = 1 - 0.01 (0.1 + 0.001) = 0.99899
+    test "update_basic_case"
+        given p0 = one_step(0)
+        when p1 = one_step(1)
+        then p0 != 1.0 and p1 != 2.0 and @abs(p0 - 0.99899) < 0.000001 and @abs(p1 - (2.0 - 0.01 * 0.202)) < 0.000001
+
+    // Weight decay pulls the weight toward 0: 2 - 0.1 * 0.5 * 2 = 1.9
+    test "update_weight_decay_shrinks"
+        given result = decay_step()
+        then @abs(result - 1.9) < 0.000001
+
+    // Plain, momentum and Nesterov SGD all reach the minimum at 3
+    test "update_descends_a_quadratic"
+        given plain = descend(0.1, 0.0, false, 100)
+        when heavy = descend(0.05, 0.9, false, 300)
+        then @abs(plain - 3.0) < 0.0001 and @abs(heavy - 3.0) < 0.0001 and @abs(descend(0.05, 0.9, true, 300) - 3.0) < 0.0001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // learning_rate > 0
+    invariant sgd_constraint_0
+        assert valid_input() > 0.0
+
+    // 0 <= momentum < 1
+    invariant sgd_constraint_1
+        assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0
+
+    // weight_decay >= 0: a non-negative decay never grows a weight with zero gradient
+    invariant sgd_constraint_2
+        assert decay_step() < 2.0
+
+    // params.size() == grads.size(): every parameter moves
+    invariant sgd_constraint_3
+        assert one_step(0) != 1.0 and one_step(1) != 2.0
+
+    // If momentum > 0: state.velocity.size() == params.size() -- init zeroes all of it
+    invariant sgd_constraint_4
+        assert init_zeroes(1) == 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/index.html b/apps/website/public/learn/index.html index 8abd0a8a08..68a881f968 100644 --- a/apps/website/public/learn/index.html +++ b/apps/website/public/learn/index.html @@ -63,7 +63,7 @@

t27 basics: the language in 27 lessons

Before the FPGA course: what a t27 spec is, how the compiler reads it, and what it gives back. Every lesson opens one table or diagram drawn from its own spec and one spec you can run in your browser.

Course 0, 27 lessons, one infographic and one t27 spec each: a module, constants and types, functions and tests, then the compiler's stages and the 7 languages it writes. It comes before the FPGA course.

Open the interactive course →

-
  1. t27 basics: the language in 27 lessons
  2. From zero to a chip: FPGA programming with t27
  3. AI numbers with t27: from number formats to a ternary network
  4. GoldenFloat with t27: one rule, seventeen float widths
  5. Verifying hardware with t27: testbenches, waveforms, formal, mutation
  6. Clocking, resets and clock-domain crossings with t27
  7. Buses and peripherals with t27: UART, SPI, APB, AXI4, Ethernet
  8. The ternary machine: from a trit to a running program
  9. Arithmetic and DSP on the FPGA: from the carry chain to a filter
+
  1. t27 basics: the language in 27 lessons
  2. From zero to a chip: FPGA programming with t27
  3. AI numbers with t27: from number formats to a ternary network
  4. GoldenFloat with t27: one rule, seventeen float widths
  5. Verifying hardware with t27: testbenches, waveforms, formal, mutation
  6. Clocking, resets and clock-domain crossings with t27
  7. Buses and peripherals with t27: UART, SPI, APB, AXI4, Ethernet
  8. The ternary machine: from a trit to a running program
  9. Arithmetic and DSP on the FPGA: from the carry chain to a filter
  10. Neural networks in t27: from one neuron to a transformer block

All lessons

diff --git a/apps/website/public/learn/lamb-and-large-batches/card.png b/apps/website/public/learn/lamb-and-large-batches/card.png new file mode 100644 index 0000000000000000000000000000000000000000..df675ffb1657dc4f9449ee705327b8fd1f5b164a GIT binary patch literal 55235 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/lamb-and-large-batches/index.html b/apps/website/public/learn/lamb-and-large-batches/index.html new file mode 100644 index 0000000000..8067f34f37 --- /dev/null +++ b/apps/website/public/learn/lamb-and-large-batches/index.html @@ -0,0 +1,321 @@ + + + + + + +LAMB and large batches: neural networks course, lesson 21 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

LAMB and large batches

+

You will learn

How LAMB scales each layer's step by its own weight norm, so one learning rate suits layers of every size.

+

Training with very large batches needs a large learning rate, and one rate can be too large for a small layer and too small for a big one. LAMB takes an Adam-style update for each layer and rescales it by the trust ratio, the layer's weight norm, capped at 10, over the update's norm, so every layer moves by the same fraction of itself. In the spec, the weights (1, 2) times a scale take a step whose norm is 0.001 times theirs: 0.00447 at scale 2, and once the weight norm passes 10, near scale 4.47, the step stays at 0.01. The spec lamb.t27 computes the update for one layer and for two at once.

+

Try it

Read the step at scales 1 and 2 and compare; then drag past the bend and explain why the line goes flat.

+

Open the interactive lesson →

+
LAMB: one learning rate for layers of every size
LAMB: one learning rate for layers of every size ↗
+

Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing.

+

specs/ml/optimizer/lamb.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// LAMB parameter update with trust ratio clipping | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: built with `append` on `[]` and `range` / `len` / `pow`, so it never
+// compiled. The math was also not LAMB: v_hat used beta1's bias correction, the
+// "trust ratio" was ||g|| / ||v_hat|| and was computed, then never applied to the
+// step, and m and v were never written back. It is now You et al. (2020):
+//   r = m_hat / (sqrt(v_hat) + eps) + wd * w,  trust = min(||w||, clip) / ||r||,
+//   w = w - lr * trust * r,
+// per layer, over buffers the caller owns.
+
+module Lamb;
+    use base::types;
+    use math::constants;
+    use ml::optimizer::adam;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_LR : f32 = 0.001;
+    const DEFAULT_BETA1 : f32 = 0.9;
+    const DEFAULT_BETA2 : f32 = 0.999;
+    const DEFAULT_EPSILON : f32 = 1e-6;
+    const DEFAULT_CLIP_THRESHOLD : f32 = 10.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const LAMBConfig = struct {
+        learning_rate : f32,
+        beta1 : f32,
+        beta2 : f32,
+        epsilon : f32,
+        weight_decay : f32,
+        clip_threshold : f32,
+    };
+
+    pub const LAMBState = struct {
+        m : []f32,
+        v : []f32,
+        step : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // m and v are the first num_params entries of the given buffers, zeroed; step 0
+    fn init_state(m: []f32, v: []f32, num_params: u32) -> LAMBState {
+        var i : usize = 0;
+        while (i < num_params) {
+            m[i] = 0.0;
+            v[i] = 0.0;
+            i = i + 1;
+        }
+        return LAMBState{ .m = m[0..num_params], .v = v[0..num_params], .step = 0 };
+    }
+
+    // powi (b^t for a whole t) comes from specs/ml/optimizer/adam.t27 through `use`
+
+    // Writes the moments for step (state.step + 1) into state.m / state.v and the update to
+    // ADD to params into `update`; returns update[0..n]
+    fn compute_layer_update(params: []const f32, grads: []const f32, state: LAMBState, config: LAMBConfig, update: []f32) -> []f32 {
+        const n = params.len;
+        const t = state.step + 1;
+        const c1 = 1.0 - powi(config.beta1, t);
+        const c2 = 1.0 - powi(config.beta2, t);
+        var w_norm : f32 = 0.0;
+        var r_norm : f32 = 0.0;
+        var i : usize = 0;
+        while (i < n) {
+            state.m[i] = config.beta1 * state.m[i] + (1.0 - config.beta1) * grads[i];
+            state.v[i] = config.beta2 * state.v[i] + (1.0 - config.beta2) * grads[i] * grads[i];
+            const r = (state.m[i] / c1) / (sqrt(state.v[i] / c2) + config.epsilon) + config.weight_decay * params[i];
+            update[i] = r;
+            w_norm = w_norm + params[i] * params[i];
+            r_norm = r_norm + r * r;
+            i = i + 1;
+        }
+        w_norm = sqrt(w_norm);
+        r_norm = sqrt(r_norm);
+        var trust : f32 = 1.0;
+        if (w_norm > 0.0 and r_norm > 0.0) {
+            trust = @min(w_norm, config.clip_threshold) / r_norm;
+        }
+        i = 0;
+        while (i < n) {
+            update[i] = -config.learning_rate * trust * update[i];
+            i = i + 1;
+        }
+        return update[0..n];
+    }
+
+    // One LAMB step over several layers packed back to back in `params` (layer k has
+    // sizes[k] entries), each with its own state; params change in place, each step + 1.
+    fn forward(params: []f32, grads: []const f32, sizes: []const usize, states: []LAMBState, config: LAMBConfig, scratch: []f32) -> void {
+        var start : usize = 0;
+        var k : usize = 0;
+        while (k < sizes.len) {
+            const end = start + sizes[k];
+            const upd = compute_layer_update(params[start..end], grads[start..end], states[k], config, scratch);
+            var j : usize = 0;
+            while (j < sizes[k]) {
+                params[start + j] = params[start + j] + upd[j];
+                j = j + 1;
+            }
+            states[k].step = states[k].step + 1;
+            start = end;
+            k = k + 1;
+        }
+    }
+
+    fn cfg(lr: f32) -> LAMBConfig {
+        return LAMBConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.01, .clip_threshold = DEFAULT_CLIP_THRESHOLD };
+    }
+
+    // which: 0 = m.len, 1 = v.len, 2 = step, 3 = m[0], 4 = v[99]
+    fn init_probe(which: u8) -> f32 {
+        var m : [100]f32 = [9.0] ** 100;
+        var v : [100]f32 = [9.0] ** 100;
+        const st = init_state(&m, &v, 100);
+        if (which == 0) {
+            return @as(f32, @floatFromInt(st.m.len));
+        }
+        if (which == 1) {
+            return @as(f32, @floatFromInt(st.v.len));
+        }
+        if (which == 2) {
+            return @as(f32, @floatFromInt(st.step));
+        }
+        if (which == 3) {
+            return st.m[0];
+        }
+        return st.v[99];
+    }
+
+    // update[index] of the first step on params (1, 2, 3), grads (0.1, 0.2, 0.3); index 3 = its length
+    fn first_update(index: usize) -> f32 {
+        const params : [3]f32 = [1.0, 2.0, 3.0];
+        const grads : [3]f32 = [0.1, 0.2, 0.3];
+        var m : [3]f32 = undefined;
+        var v : [3]f32 = undefined;
+        var update : [3]f32 = [9.0] ** 3;
+        const u = compute_layer_update(&params, &grads, init_state(&m, &v, 3), cfg(0.001), &update);
+        if (index == 3) {
+            return @as(f32, @floatFromInt(u.len));
+        }
+        return u[index];
+    }
+
+    // The layer-wise property: scaling a layer's weights by 10 scales its step by 10
+    fn step_norm(scale: f32) -> f32 {
+        const params : [2]f32 = [1.0 * scale, 2.0 * scale];
+        const grads : [2]f32 = [0.1, 0.2];
+        var m : [2]f32 = undefined;
+        var v : [2]f32 = undefined;
+        var update : [2]f32 = undefined;
+        const u = compute_layer_update(&params, &grads, init_state(&m, &v, 2), cfg(0.001), &update);
+        return sqrt(u[0] * u[0] + u[1] * u[1]);
+    }
+
+    // Two layers (1, 2) and (3, 4), one step; which: 0..3 = new params, 4 = step of layer 1
+    fn two_layers(which: usize) -> f32 {
+        var params : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        const grads : [4]f32 = [0.1, 0.2, 0.3, 0.4];
+        const sizes : [2]usize = [2, 2];
+        var m : [4]f32 = undefined;
+        var v : [4]f32 = undefined;
+        var states : [2]LAMBState = [init_state(m[0..2], v[0..2], 2), init_state(m[2..4], v[2..4], 2)];
+        var scratch : [2]f32 = undefined;
+        forward(&params, &grads, &sizes, &states, cfg(0.001), &scratch);
+        if (which == 4) {
+            return @as(f32, @floatFromInt(states[1].step));
+        }
+        return params[which];
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_BETA1;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test init_state_basic_case
+        given num_params = 100.0
+        when m_len = init_probe(0)
+        then m_len == num_params and init_probe(1) == num_params and init_probe(2) == 0.0 and init_probe(3) == 0.0 and init_probe(4) == 0.0
+
+    // Every update is negative (descent) and the step's norm is lr * min(||w||, 10) = 0.001 ||w||
+    test compute_layer_update_basic_case
+        given u0 = first_update(0)
+        when n = first_update(3)
+        then n == 3.0 and u0 < 0.0 and first_update(1) < 0.0 and first_update(2) < 0.0 and @abs(sqrt(u0 * u0 + first_update(1) * first_update(1) + first_update(2) * first_update(2)) - 0.001 * sqrt(@as(f32, 14.0))) < 0.0000001
+
+    // Each layer moves, and each layer's state advances
+    test forward_basic_case
+        given p0 = two_layers(0)
+        when p3 = two_layers(3)
+        then p0 != 1.0 and two_layers(1) != 2.0 and two_layers(2) != 3.0 and p3 != 4.0 and p0 < 1.0 and two_layers(4) == 1.0
+
+    // LAMB's point: the step is proportional to the layer's weight norm (up to the clip)
+    test compute_layer_update_scales_with_the_layer
+        given small = step_norm(1.0)
+        when large = step_norm(3.0)
+        then @abs(large / small - 3.0) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // 0 < beta1 < 1
+    invariant lamb_constraint_0
+        assert valid_input() > 0.0 and valid_input() < 1.0
+
+    // 0 < beta2 < 1
+    invariant lamb_constraint_1
+        assert DEFAULT_BETA2 > 0.0 and DEFAULT_BETA2 < 1.0
+
+    // epsilon > 0
+    invariant lamb_constraint_2
+        assert DEFAULT_EPSILON > 0.0
+
+    // clip_threshold > 0
+    invariant lamb_constraint_3
+        assert DEFAULT_CLIP_THRESHOLD > 0.0
+
+    // name: trust_ratio -- capped by clip_threshold: a layer of norm 50 steps as one of norm 10
+    invariant lamb_constraint_4
+        assert DEFAULT_CLIP_THRESHOLD == 10.0
+
+    // name: lamb_update -- bias correction makes the first m_hat equal g
+    invariant lamb_constraint_5
+        assert powi(DEFAULT_BETA1, 1) == DEFAULT_BETA1 and DEFAULT_LR > 0.0
+
+    // "You et al. (2020) - Large Batch Optimization for Deep Learning: Training BERT in 76 minutes"
+    invariant lamb_constraint_6
+        assert powi(0.5, 3) == 0.125
+
+    // "Used in BERT, T5, and other large-scale Transformer training"
+    invariant lamb_constraint_7
+        assert DEFAULT_BETA2 > DEFAULT_BETA1
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/learning-xor/card.png b/apps/website/public/learn/learning-xor/card.png new file mode 100644 index 0000000000000000000000000000000000000000..7c9aba3eccebe60660401f607028cad5c752f82e GIT binary patch literal 48383 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Π3Z1BwT{;YlW00htl1;_QJFatKx7U%zY&q7S{u(dX1JrxkfZYeY_-) z4--n3&sLCW+wxofn#wp|-Z9b{PO47U%$hdWwnLUoq+;Ip;eWk=&H>84(b4xprVn+F zbDi|8E5}KZi#JcrHB)0&ZT7IFlYWmiNI?-bKBB^wW!5;RcNLw$yrKsTruzIMA~p(`y1x3ghoXrvj(Unq}GxqYt9f+M}?tm-{1O^YzI+u}J>gh$9rf_|UcX z`V+fThnb0gNj<3ZC_LAd9$@MUmg1JB_-=dOymfvSIgF+@$FbrTm=GW4c1H7YqqL5w zH&h+2B$HG*c-tpqKFtqRv_HYZ8jpD^s$`DoP354S%H^}z&0LQ)tJ8PMnFs>vh&v~D z+D#l%8-_+ysv9@UPGhA9C?yrS9lsJ4`=J7qm$3umJ%FM@7078u+IeP(;aTvM)ENlF zNFDZWYkS<@W3JUED6}2*8IQ~$=8uQS?QRRNu&Ts0pqp$PS+}vtP0aj_-$Orrn*91K zq~~)#UEX)Tg-t$J6VXD3qM<{b?bGM_>x3yO)lCnAoTAn4lrv2_nj035Y}3 zI^1B(iJU27zIL=Yv)FKO-`sx-T?^EOC5t)SFE30{N0SJ6Zcgtb8kTP{A(!%c=7kgO zrkNjxtO+<5rnP5O7wPIX*ktrSL4e9Bo_F?1?)i>N|=Wpa#45xX`c% zLa;7FPQJwpfWBuCvL}jH)7-oo_EU6AQ+r!pRD9V=<6hWO%-jNDy zrZRpyISVS3d5vyou!XQLozG5SyQ|Yr?U9INE%6n2WS?CZGp-T(nuCA6HF(hVntqTU zE|IZ@=Fl;d^H|13`hprxjB~(O>k8sp25%s-CBr58C35N~iy-aBxOT-~L@=h)U#jNW zVj9jNAb5u@>_2TnBcStN1+?T?wy_tmQkMHXIQ&@LMbZOIGR&WgzIsLs0Gj<_|RwY(;|ma#IL zN0zGj*MGqnwWk0?$FVNY<4R&+{p~8R9tB47ebEe~fmyh#%QAA_!)RY-`xGoRt|>i} z%!cfYNd?!$N6_XxJxo#A*5~Y8n{g~t=;3Y;k zE0bAYdex)!M%I-^9(OH$_%64}zl-@*L_2iC%+BU=xfrl~CUz4ngpT0naLr9G3RY%? z=i`5WuN4@kiPqY?1N4xD9Q&H0(e_+~lYo2qRGz+{wcEx!mtmapuRM3_qq*sF%g$s5 z5=Q2KnsX~m%y=3hJKLpO>AoiTa%96&8;&|lkiDxws_%M%5~Z*>W)pxG zycQW9rj?>LucXM1Ymp!hS~wXir1rB>5fib@=(zAI5dxo2tD7J`%d>)R8CPKW@mG>Xq0uS7w z5lrC$ovOKydBx)MRZfUP?u_xiL}rX*NbQks*9!})EIV~Kdr`V-Bp%j@_*3(o4ZAE5nr!T-}S00hwgLyeK9h=tdQ2Mo1)%rRSb zE9^gnGaZvzd`@7;%~H`$+P4n}WVK{%Ej->orOi$i0FihndW=zc=SIxDQs?uye30H| z^j9Y7X&fR;mcMZK2r0bjX==P3^*n->J~C#)%5ZOrmThGANuN9q@<%7=8v)G>sAgX? zvLBeRp@1{!0w^%0y8%gvSshkiB11sj%)xo8a1FChomc`nj175!Jc^}_{Nvf4Nc4Q) zIfSNk=0x-%@NLT=`F-YNX3Rdwy`sWj3tpwCAC!{|0XWa}xg5X4i|Ku?kC5+w{tt%*%tXpuB9*ie5#+i1%NP?r&%gRle|op{A_MX40Y*5bB| zf79!V4_;(HBwT-aQiJNIKPxmk%Mt%pNtuUi9ej*0qe{w znvcJGD0EG>mv__?|49bg3uwryZN1~d$|m=+>6G#rnoY7F(^foR_6}pK#z31C|F`wm zw>h2|;ds+@?&jlAZ<8+ACIl(#J2?kz2k{p^N@gh?ooU zw2Pm&?IagN{kbdl-tsEtrGk6}*y^BGYv5t<1D}k?z`#O+)VHpUh`d^glNj|WVy|}F zWw!}fTW@evi*%L802Jz@Z*V9Mc;?-c|zYMC=h)X1#p@(bq zbl{%0p!f+^tRh;}!`Wvuz|*IwM*mXImai}7?Wkw3V6D;_^(UUqHlA%V0U=bEYDi0r z%IvM8h=!QGw`E2q8@*+I*>A8r8Z_vrRwXVX8HF>rbkCRq%6K<;_`2ViZ6kJAG)M|k zS5}cn^S*~#-S?+n86N&HexXSoN}Y6+y}psXwT`!;&QZ`TS;{}Ios$|u8-Ln9Yz&>D z$bIz`7>q@R0J2v3(o648DL2VvUIAXyEZHEfHMCf^Knj~NvQ9RW^Dg=}+CA^sTIa!V z>+aCfB!hbCJO958-PfJMud`=bZQ}z8BdIGw=qPCw#b|XOHGaWMB!kgBYsq%7CHhVXy%YZ`tX2N{gxq_jb4yE3a{f~ zGY*S0u*|LyTTSw-Keea;U4dO+QI zN|E|iD>5FZ*P34A&9SR|Gp&CLeQ*#3(|O3G8`bBVv+i1BaJX}0N88#CImU?l$ zcap`Dpt4gXXH{{kPqJrLoQUe}MeZeLhv71WC;_E~gy^U9XSY$;W6kvbfrI2dM#_n6 z{$2_?{C+ER`DaHc+rlp)@&0`j0TSa)Q*t#nMM~WAQnAHC3cqYAzTaG;xSj5WQ_S5R zT_a*VfpqR>%E?c!o8#$euLNo_MLgDIonltIm54%~^}gWdoID=svJ+idEv<)19w{Fv z2s+#YBS}#G%`6iZqP0+K|6AI0FJFALtVj00UO>NfX>5E>U6rCN?jVP3cEPV^eR(__ z+)|ktvXe`5R&v8)%t**vb`-wG>WLmVTSqO&G<8Kwk%vXm(o;M#<||a?;?TEIe)V*` zvPn=+J+2+W_W6L2ycW0MFIkT2Jya-FQ@;{*r%fbyv43tE-9>{6i7pUImPlUS+MYkk z1A}}9+!D~dRWxmejDZ#;B1<~AkypajFF(6mUQvLh4uO2U+Z?Af-f4!pYL2KWmTrhW z6~r$Sk*o>da7{ymA9qsfHzup`m4-AM{Gfn2XB%kTvygRS*eV8V&2yAW1!FzeD zFZ{u%0Zip=+3k|bCMK<_c;+msDYq;;^l^13jQQCY3h(rHVtWcmc=J}CE{vSIaMN9v zmF#G@U`0tf}g7dWigU)`+JSsP8d$adL!ZMt^G# zD9ExS>rCP%%UM{+((JtLgmq71PlHJGdvuRE`V%)@yfYXxKVZvU>gF8McSAz53!%tX z%_j?efz9Lb()R`YXhEqjYy19cXMGD($zb4{W#Xqp*<&j$fP9yuDi(}{g-3@+BB5Vg z=KjnmNz@l3eq?5%C#NshO=RYT$zJ}fjx#daGQ4xM&u2_#L(p6kJg?WsZ!*o+^pw2sf?jmB|)|fYc#}CWD{<}Fp)_?t|%wGMd0%xMf zrXEvO+M3eE$JNa&%Wfat3QP&;j)qKbECGG9y9`-l-wxr~+<0xZftjHpn4U0xGXB~e zsw$)Gql?wI!ds3aNhGW|1fmqXqd2-&t()(ZRxlMPweo5CRVg>8s@(U}SR6cIs0Y-y z4cT=HFrO~UGn=n@7TFj?N0XPASI>f2+-5e9A4;odgXPWnTv8><)CM?dx#;_=?eW_~ zcnr)%L?_6nz9&Z0qEUy+`V+@xpJBG^`fuevX#I)vve%hXco!UivEYOjA0(BXrb`l`r|(7m`T_vSfusoh&?18K<{N z)bM|B5f93Zl%qyLFT$p9=#3f;w$PyE9aYka7af6yBiXZ&PH`Q7A08fblJ&JR^ua8x z!^{*wF_L-@pItOQen`R@9}m@Ao)7d5UGNaLupsaVmMI4;%?6DP-zrZn@sjUmnpAV^ zc}FelwY5j0G6e7N$?%8WxMS0Kkvt4U#0;y)1yHyfnygd|9aSL6s0#x&^;TN0Ch*)~ zBTGF4l@#jc{*P~?A`9L7qpK2Q79p&2^4p4zVbZ9Ms=fI;9uw*@X69P|Kys;^Q(ye0 z>hUFXc4D?SJv6PPYnJ~gD{5U7v~mslJ(yp0CPk%K|F6p9?uv(``*y){>k0iuEjdN)gi?|ROfYi-4*V*zSZZi>PlGjVG8~^S+ z^xZk5bicHW2H$%DsK&}zzsYULpNhFX-2D7wn>DntfUH}Mr>pOD%>NC^Z}#(YCWQ2^ z{G{)2;(w(8O=i2%5^jR9YGrJSho59sE(Y775AljP4od7OWnLdR2~gN$H-8%0=uplB z4ZYj-^;=_Ey%<%A0%&~j#bkoG*vEMdgnFqCVMS@i664>W2IYYH44h?QGHy}Du26Y( zad^Aoxj4(qzb`X$=z{3v|6YFI`kz_3{|)8)9ZgP7jzPT~6$1kU3CZ5ciGhx8 zq213b3jw>Sn7FuH2LD3t0Mw&wSJXqYg6I4I0SMR+an4LF?jd2trLYTrj#cXu}vjdrUi z)M-qh5000`WDtC_>UG*nWM_TJUk81D*b|zPMs1?x;sQoF1mClYOivV)m!H5O6+)g@ zv=DSNv%S}d=sI4+;*!nJsaF> z-j_cRNij1K2Kr+t?b_~kX)?VpN-ElbIvN!oZX`OOs;*mSJP_O2DS|Sff@SuyDel08 zrk2Nf4?Z27^A&x3BbUwM_Tk}R7T?oFVtWWPY$Sy<+z}spWNggt?qY|6#`hpUv0J^X zyyZelst_juk4a~LbFaR?y$*{D zlX!5Xq@|=tJ+@;MbH%ILuyJs%CM3unPyL>W_*_2`85YQ<{sFoMbyjne7(ZSfW%LDj z)H`D0PX%<=mp_&Emrquj^?jhKG1y)n9*V_k!{GDt^ZHfKk|eqjQ+8SJjm|)(!aVrf z-BdeEj+7zh_B3ep{b_r9Q4#IOj{#_`IAxi>umiVMkKq6R?&NF-z-zjoHl5n}-7mSV z`Or8T{-zyGV$Hp@SYBC~tI!|o_Sgu-@7DPwrGEkh#C@O8lcF&*j{uj)#kOv^T%t%qO+MDW1N7tCzzFxkPz1g9UUFoao>mYKI?stivb$CxEBwl(hV5bWxPIJ zV>Ye!N5o*;kIBi&c{!HtZosv$nk_xppBWz?XR^D+NgCOG^A^w9qiX-^UWgCC4+J*nW^Xhdn?1jz1d?jkw(xWZY?&R!={CRp`d{`j z{;4~TT#4wX{oH6VJ)cGS*>YX4)7G2nwn|Uv;k!Qpfq@eztxkJ#=QTM81i*9VIpIaV ztD(GotM9%M7^SyTZ%4+vwBLGh;dtI9wCp&<7|nkX0%eb*mc{xU<|!)L_4CbJ-$&@& zC{1q84s;I4@#w)GiD*(rT3YwLbT=g>rB$Dsm9(_9$w{SIAC+V8tw?T|%cn5r_J>$C zHfn0q>!Sss$E&!cdU$wvnPj%Wmk4_7d?bgnQJlX80HxUFWMjj?BX%%oU|>LA@XpxC zh|*ur3p%4tmjK{iSn}=NUgq<4PUFvX1BrXlDNY{R^B6%XiX7 z=L4+QK!`l9uzUE4et@ss=)w?MZgeVCD$Yx26{ENVo?I*|v-1JLXD>ULlo#0W28XSt zG$rad#qVi+ZcGAEk&*d?_}D)N8zHl05JxttREoYj{BeH1gG2GNt!SaP(OiwM*(wh_ zR2V`JEV$=IKL=q8`1;;eE)X@=#}IUl%#v>vL0){wa9K{S_PcKrBmS9p-ROK{nRvQb z2dNnoSG__w=7(iT!Vt z>9U@7x!Vsqel|&$%!DN$rC604!1)Bod2n!XZSpF?y+1iR;tBdPe`?!u-U}qMzQ<1d zmPbZL1}P~iaB4IjG;(Q0MMd*XE>>jdHWHxdwZ{{;IG~EL7<6`rVjr~E&Sh-k;^G2F z>!nin?RC^*_w=x8F^5^`{(rpymFcX)NEX+l`K`Wa<;V~NhQdvsfU_kQ@Z=B@dLGXfwJypT**rcLNahC0DUfLsyvinQ3=9z9g$;bj zd3jUt$PWOfD zKWw!5a5v_6BKtKr`r!1G?A<$Z(@h}utl|F2?$6=2+#09ZA0CPzV4t?E6VL5PpNC`d zR?LNM_Jjl2ZDVf!?fRb|mF+sN3nnTzSt)Q@)r;5RyQ;V2(2EBqcI83JCbzV|kR zAQky<0-$j127B_y9-HUM_!dY-d&VSPU_MYjOaPd|!KaIL`Md2Ga zLAsmk^k)>GFTaCq7OHoq zfGC5#EU1J4hS1hD5yF+;KXF;aGtix#9{dLjLc%Ls z-vn*9o8i-H-!^}raf|>g>>R*6gunM->17h z3g(_83>Ea177um^V^d; z&1CSp{8lSDRzuJH>_q*hU)#13w0#AJqdT0kc*D)jO-&e|SL8f^fDs=PO)4%8ax^sNg?SVdh!2A)yp)bv7b|v$lPOIH1@H9WLc}N<-OnjrUO@aT zsrAc;BWd7|trQg}Uhv&B*l`r#l489G^kvR$zhEpPWMa7!A(>Bu3>C&JVg#Xsm4;1= zr!?5qGFg*k5b8m96?zW}@)Du}u8uov;W|V*s{GqX8&C z0nh=5edoA-Z4@>laI<`Qy<``jd@-ENt|DLx_xOEL$=Mzfrx#8wmo|R~@2p~dNdt}I zJIMm3l*6Hy=G_nOj%xl(_-=?mv=)`6G~#FySw`>40gTFj1PxO*$`Yg zHk`z|6(=uvF#Fv!JUW+r)~F9 zXk<7h&o}MQiv9(0+A?+x8wm6`H#4L>XRfEK>1k;#0O^=j2IveO0|WNws(x%H=di+t zh9qeE!-F^LoaN-Z?`_V51Eu%-tyNW3HW_)l2e;>22Vi*Im%H0iqwn-i70R=J_g&xG z5`{k4Ed5F6ao8O5dtyI6cD~*K0{b4Q{Rgy+M-Kp4>bAH$0J>x6w_})VjoH`}pfD~j zE_TN<<^3q2o{vIL=h4f{IxxO!t2w5{XS%NOg(|!D$Al-^mjnmY4u=2QPDNi;^^xWpJ^>|D*i7E{b_4PE@muM3 zpoVR2Zkp2p_oI9~UupMi2R`CzZx?EP{QKjzGbwz{y#ct6q$D4hT53H4a+$%}|;m#U9UXK=yb7s-{Pt`C?Q?TKji}LXGM+cy)EP zRD#ytcOIQ2OV95S3aExKdH?A&T$sl{`xsYlan*RoX-rH^D#g-Yzh-rd5QJI=0Yw?F zAlrzLq>4^0l2ky;J;*V9z&K~Q+W9~!#sAmNe)k9<8e~5Iq8I__qPbdrem;(MQ8_12 zTcMD-DeZ($no5d_j2l~znNdS_?G zU+<57Os~mnr?9@wjVpewQ;};AdTY{!#_97(VCs)>;h0w%Sr9lwcU*c8r%9W>5FssT zpxe1?iBUx(tLE0Q0EZn%qCE$%ENL|0m1hw8J@}EfP&Sn-QVA1xa37v_he}E~fzPQ( zO}sdIR2Hd2^2b+ zA1@tPBjI*`y3D3IAn<(q<}(UEPQ5u@?I$hX)^O5sczh1*UHN>Fl++W_k+ilzGm z27>6#8x?vQtxU%JM02WxV9D^TVeyF=ypPtz8*!6q#iNpRQGY)Az(dgFRJ)r`n!dlK}~8IOgPwQ6WU ztwQe+m{qK5%bl_8i8h^m?L2t`5Ei@3kLhUnm$}wouH5I5Sphb6%%wgaO7NU@)Ao3+ zZ5deW5i574B%L#KgVJSD>!CDUiQRg$XjM^17JeEdL3;3*g=BcuSBZTr0G(D|c?^89 zG)U5U50I!@nNImAR8rgl%B`8n>wU{o=g^#HJ&^;_{$pL`E51!$E)NES72;q(0HJ2# z(^?=ML`ivrZ2%e}ILMfwUd-~9JRl?ckU$`7TNGOvV2m`V%_7lscSyn@_qQhWFdA9$ ziI7#$W#OeTcz@r6d}yKsthY}EqZtX-%Xvn5d^PFE=w#|`jg3c-0~c7@b6drIpbOp! zaGNla){QxIypm550x=uBtNn)~`4@8Wg*bav2DyOb)YR(@DuW3Qd8tm7!Q7CqetLm4 z7SvZv25-lk&4oFfHd+(De0?_d{v4B$*H^3HS%JwG7+;8+%RRZ5Q?K!4K|mi_ke3($ zrVaR_g(vGoFc#}&p?Xj=g?hk{dxKJ9Aiq`i>I#>)l|kpi=JPn3K2ZPapI~$CVKV+; zj-nAQEiI`%9JseMx+1w(zaHzNTv}^n zQ;;7!+Avl402r4bY*U!iTrV7bYfwrc>5LXu0H9}#ZI>5;@h zAaXPjznXxqDBHyRUbWOj+9C~7ZAY!wW1eh~#80P|%B(fSUzeD58?>7rn}=Jt!YftA zK4FyFUE`TfnnLB$c~t=dmXKg7S;&!0b)|*3Xc|~%X6P|+kvGm#SDJmM52+ug_yk!- z9@1X47KN)cYA~*?7ehDt_3PJ{M#bC-1;RYPg!p(96B9)fYuMF6Uo_e2L#t(7lk6@| zc_hI}fHorE0abqcipO5MbwkX6u}$nG;I7QjtX!dyyn6L&g)n)m2~rNR%}hHvIZ0nm zw>ky{QfY-I_dV|fnR<4(0b4TduNw(01UO+6lbym$-$k-ue7NtV0D+44I%$*`R{g0m zvruahHbCh^768$y0#}5z^N#@RiKd-4anv(#BEjL;a2Bc&Sx#`j$o0Y@OG{K=4 zccaV!-^$Xm6oQ(b1wRT)f$GYnXMO8M&@naL1xOOd-(Vzr_(Ue%9Noo9ZdACxmEt=- z5Tb}+J{`72216z{Z@{T|2BN~1?Nwdt(`Dwfg87j#AqoagW&nhnRwN)Oh|NLIedA5o z&*MyefNPZ{)zq*<%)s15o=!*etQ(ol?qfpF{60CWZqU17_OVjk=Glueffm3nT+A?B z6{P)9+1BO@*f-NhfA~d-_QILlvXl|P);+@=lh34Ed>knPUVoC@I5{{b8Eo(Sw!mFQ6zoV1zzahSa%){}6ov z0>$~~I-tRg0P2bE^XAPP%Q_f984cjzy3(L%1FmpCD%Cr?y7)4)nwqp^XfP`PFLLjP zJ-{sMmmQ^DUAeZJQ!qUsmVk*o7|&qSR%*%|Z*x4~ z?D2cpB6DVPoGwzNs7OJ8d;hbD90UFQydHN$WCFr6u^Ri{P*MuOD}hwZpVjGN zWf1x~YI!yrFI*=^Y&xStM#OmKOZ zAf}!{0T;GlmWj*0LrnS_@beG>gT={E919|vP%hRDFG4Tfb~(zYE2pNR;l4jkK5GZ7 z$n6Atn|cDzY_!z5V)Q0}=(}A2Um)LWa_hRxr~*$>vPqos2E?rO*|PWL$WS7)S?l## z7e+9kn3I*ZXEV5LwAS=E=?h$C2Zx6E*1Gs^fYb=N6A65BFOW&@d~q)o0i~H%U(ZeS zC83}_X>`9Qn$V8ry+%7hH#yZ&F{Dr~ggE(&4BImx73M!UxVWq|xs>$3rQ?%eUuf~D zNrK3&`91r@@D1ocUEt43(0Yy}v5F3ZGyR@C?rA`){4#NmfK>?Q?|Fc;z@Ied5Y3Y& z2Oj(09jGUJ2=4Rd(o^~}H?Tsvbi>V%Ost@+!$V8fI9;a^PQa=>_9l$!>3uqT+1CSE ziI2R>mw*+KJA@;_x$Sd*T|8qs8!z;DAkWpzeE37PL@gB6h0pcqTdT5?l88%ZUS1yH zjYodb7tT~Mf5l4?^EE)Q7f>R>0RaI3{hAnv0S>jHxp}Iiu&8Js=u$8;GWq}x?7kR6 z`qUlZ(cc4yD_^Vv7)ew9x3{;V!RWFX{K*A=z=j9D^LYiACBI&3KNflf&Z*$w;6TFY z7UMY=)zXeOfa@9s!03}{bx24EQ(-cf4IvTgi;)gQF}|K!ZT_f)0CjW@dtTKNGO*Dhtb3 zU%>_a1K*iJwB9^zX=xdNXedsD{dt^#=Alh-DhU|5$JF*7g$+a zf(!HWH?A8epUjy8dW3Sp=rB!U|0-A$$@$7Rz zdwE?SWk1HrAt+LpmX|+mhBJ$0ya)RJG4=!IV^GM7+p(tYTO4d88kwXoW_kzC)_ZXv z2?>m|z>4vDvDI4%gI&P&Jz#~DFPC*WEKRzg#p`_x4{mX3Jcju zAafOkALa%)dU|?3fBp=ZRHY2lr1@Nsm%{l{$+9hF3=KDd zvN^j02Ha4fZ}dE3=i3Dbdld+Lqt$n1W%#f$#Aa`vYPCp2M5JD!H*!nv6lmr-z6T8K zgan`%jD?;y8H+kLI#!FE-dcrE3U5^cY06+eruz%wVpyBBpU%D*zAB%wWPkKcZAx>FGshNrO zSqI8kzbq1|OCJjeSI*KG_X(kEp;)<)jh!86XDsc2M@L6-P@m3%g<1eP{L*ge@JF1n z0@q!Nh?x;9s1y zcw8nSsfga+Zbiq%#T{5n?@@+mD0CbH$w#J&lx+UeZ1IUa>_S8*#$@+Jh{pza$^ACE z`1h!B4_X+6-Q{qaPPqVxD>Pf0dVFTRyi6xe&1Aib)0RudP%#k+TrKSwUD3L8hKfsw zu2&<{&`&1aCNU~an0dO)?%|=7^ubPV;hTxg{rBNSe6NByfz-(Trlz7IHZmet5HqyH zpjL{hACh~}JnRM3a+$OjxW8JvPX6@-*ACbX;dqROEDwNa4n+?52jz!$y{(DpU%(ZS z^J-3_12FK8t6u6wY5;KsR1=THQ|Qf2p?(Ko!_UbTXtsLR^?&KVrN#jj0FX42%Iybq zzg~K%63R;FFGy$PR`EB_u12UyJ}(y~&@xgS@KLAV=L>vfVX^jSqxV^2ghGFC5Ek$T%?zwyuO?;8W}mUD?d@Il zdw#T4WAN=ll*fd`ZF zwcB3-y?C#q6MJUoich!nyv=)4Z`u6Px7Qi>Ei)< zc?c*{1MmL4IGgmfff}17uJd}>GLZ2qkp|z|%`@)+o;MJLytwoXt?&y?j$I_U>Z)4c z%K6O~zh2&Yy~t!nvD-OOnBf^FLK*)_gL|Ul9%yVB`20vQQR#-v@x>h=IYG+m!w!~q zUyM#ltP`4mHc;{&P{G?af`~kw1dRQffr3JNugP0Ot}>PT|FQO$VNrcy8#g?NG>Xz8 zA}Z1#E!`m9-Q7dCgh~j~-CaXTcPJ%YLkJ8YC^6C{($AXzec$hKyx*P=4_^fw_TFo) z>pIWhb#8Ng_K%4e)RW`6qAKZ=emO}cl$4a09X&Ef34cP8;4I6{>W_-8rV8{-3a=SG zb{+LdfgW1+_)Htraj9@a(DNODXa?od!s&G&7larz0dNW0ee<{b_UsEWG0c*_NE~hU zHLPxa2%j~e5$(~i4luMF(|&-iCM|P;T-2ivI3$i;QqfG2D$g@*Z*Ombc&`SHTbSU`nd!Y zalR#M8(6B0lb%voaq3-dF{bGq6ZVUaSop1MW(O`ypSZf!xh{~A2*I8W{hOH8*=Ua- zqHiMjOY9+gNDjg0!w%_`mi@}_zIp2CQ8zApxm}pey`1yzcnBp^qaA`~nJ4J>x=T2E zc?c1Q&2B*P^Dw6`;&|(mFf(P6HQB$L8*hdB_Qz{-iJ4pUeV=E_|g^{ar*@h6gm8LW3QR{fX9FDb`Nn39`r zwMYIKyPN^#p#P-?hx1Cu-yoyy>*pB3Jv}{to1;EjfXdqc=XIXPq9^8U zm~;SM83K0p5&#|6a(p)_I8vR6?Dr@8dTi&Z^NT!2Set>hN_G0n{3ez%l#!7!R`m7_ zm6+!Hd_Om3<(M?0iy6Y=_42fpdWe9mUEk%TRJW`^rerIqgu2pRo88NgD7dB#)Vwnmr}N|R-XDyi(q+-31Nq!ioBvbVOiEq1geXouZ$ z>i}>GoYTMt2A*xHighGT-$xTtTX98drF2Jl*nj*mH>+c!G!$9zijFkH6i70KGSP&7 ze2-DUR?;a$|CGWhsk|z2$aX9bow~eggKY+XF?&X^abt%9IakfirN(0ZMXr!t)ZKMjQD(S{r3koFO7I8l)=DDP|;<`*b6}uku2bVl^l1Xj4kc2d+NJSne zdOUT?ERs}-SyFtwxA$XCX`IZCBz=h;JOF@8Nd@hdGioKp+9A2QG_0SR{w&nn*gas) z&ES1#WtSmZEU1qa*+LwQ{52^Hum_K%l4zAoC~$O~J_tbYWwAp7HUU^sQjbhIu?#Q= zcDE*MyQuTu^~t*_4zmB#0w%my3^3nN3cwT}FqR8??mS`5b}kt}+u;LZ+Io9s(S0}I z3BRJu<|Om2s!YR^#b`id)c58bHDy;5em~w$u)h6J^PGrZA7|FM?BTPz2E56~m+|@p zP=2@HZ`b}v(JK4+`f_w_%YKVWz!c6~Wz3c+u$4V1_$q_NJ?uv8&+=Zir7>3CEa{wq z?eg+cJv45eMystXl5S?z7Mf(qpo;U08Psa8yZ%ZOX@nFqNDDT-{_{#}pzI`));nN**lFS6;W299Xer67dbAXJ3cCD+2$x7wgmUX+2^e^T z3KrMM2+Dw)(y&PUXS=h37&jf1j;)7;PWQ|6aOpGz%!2?^wMclwn+(ya zrQbt|fGuM%^6q+8&T)Bl1z)logVkIBI&a!0-xv1_(7FrCju41&soT!z+2aUMkOTd)-!J^uOC2dTs(TMrxOKE6pkJ5=(7YjlC)XnqcN+g?MUN2V-EA z_6R5n`u;An2;o;|R9of|HE=bvs zBoGD`BE2=s8+#j+UIcb)D~Pake1tk~F*R-ZR1o7wjxI9j6j!0O+CwHf z;gNXDdlP<-lWexT=g=!A)kA35Zx9RyxaS}nqfpQ?7)bvHGXOVIGny^j;QchlII zvkP{tl<%5jg_ds#7EceXE{gHK;Mz8&C`2-d>&4=WV{xy&fBo|{H3!QYlo3fSWnJ|mOiszatuKddFV@( z4XJ_EHalT=g<#@ItZ!!pklx2kApue2D{9#;$m!xvShJ;-)zm7}(Tfo^*97Hv`#_8J z#LBKRY_umq7nHVX0n8VMv-1I{DH4xqi&^BYT3cI9_zH=>660)Jo+QvIlrg^G9ubfY zm6{76{wihc{$uFt$83L4u=m}q18trI7@P4#rKP1BcnKmBslo`4i1BZ5P)jqCC}8nD zz%6S$2M713tbd^W2M&`dxZK@PT-MHxS_!7)zm-HIQ-!iiyYJzz%Il}r)O-w0OjHi6 z0;07C5+ID?YP8jY2b(>mgTG!nu|-Zkc<>;q`(etxoHT`(EQ>Rqg7YPCN(i}(D(x=W zmqTFOc>~@_qfyneoBdT{gng8zK#fQ&gSxM;ucISN<1MWJ0x)A;M+;y4{D!4WVZ5h?s_G;VRv7`jSnbVyXu8EvHKi`KLMFR40%P!lEAer- zQc_XPR~ejxZdgWER#sYi*=xxOg~weO+bd7mc@D49fL#srWkY`9&$H5=dQ_^MctZgw zIulH^ph|iNLvt)xB+KsV00d6h@!)+;az#10+EZI5d8odP(-ry1Kdmve61Wa%9Icqp_>&5z60Fsk4%gj5ivOUQ7+}cm5sc368kW zc8VI2`yKVeWhh2BN9@y8%>& ziG}6OPq8roy8mD_$R~JLwiM$Au*`D!-Ag7z@u}|F(lPQ(QDp7z?q+2@$%M&lHzeXZ z5ZC&>UT3CGhhZ{A)#;j;IJ-Y4CPr%cA@9YWVUNA%EOoIfOSf^iVj!9>&5M=9`{UX; zS;z7`>hCwme}S*~te`!}S3L^=`06cy0wR1z+B|opR+P%sVP%6L;iwN;mdy>kZBU~o zJY@Ve07h==)$Z~KrOvJa=kOOi3&@Ue#bLEmJ%%Q=m_6-ZDuX@}mVbl-&U_w|Helm6 zgJ(O{C!1Y?L1+5!!9v}(B+s$S&a*dfKzb~>gx5You5^XWrQ}MTrHV1$jwR>B8kXECJR}6U8weBu}C2 z(Y@ehR9Gn{Me;wu*|~nF_69UAc}pu6FmV95>i4H^gbfcL-^0~4AFl54Y=;Zgj{tz<=_^ z(o$1_7oehs;_UcAE0M&g(V)-TDdifU1Ngm$`uY=~6ou9vlb&hyF=IUgf@Wh6r#~oDgcd% zn;aii0N(|Ik_d=G0DBz$c>!t#vqOM66w@aGN8z{r6oIy3&!3206tRNT!ei z`$GOtS^h~&PDWzf@?rJAC6*{GQZbVkRoQC3wuDSNkcWety$Y@YBhlZzXYYZeuHWHv z1ZeOHaI;a7$GcDe%P|gi0%W!6`Rm>P3BiTn>-@h6M!wowU+1(MCZ?w^1?p{%pmz)! zkjsSddDIjB zgm0#KtfJtuTs{v8>bkqVLd`88@ysEUg5+MP`K~;?BuSuk=(Dr4<14(8ilPx+0g$mH zFBinc=f6)o+0AC$(E`{FplRtcX}pe z<*fL!va?Z&qu_pvkVwj(4g z?A(SdF>vnm1RyrJ|NH=A1|R6p&Q3cRg8&Z@*c^aC4jfB>ewr>e*a5rgJJ<*8>SUk# zT22?qfqnx8oP*Xc*Y6Juhv?N4L9eJBpy`{Wuo}FIe+yM>BCP-r!cAaAAv@J!N!rd}3ZdQm zpoAy?Tm&p)l+yt|USdLmyn=$wScWvSjKj{sK@d2%f`FC+Okher=#x%)csCII0IyVC zUET1ke&HQBo=}Yu_)-x%k}@({20iiH&s3mt2b&TBwSWikW>$dDu3t6hS2$&0n{D?{ z2l!y%?+IM*!@*pZS`y;tzW`-1KyFR!sHVM@{AYk~p=o5K^aT?GV@gEwPEk>@DAkt! z9bicDaB;Ukm+<-d_}o7MCxW=YqnH>ZV4jwic4}&B-q@ctzyZKBdCrG`VfY8yUgVBJ zgYDzJ$OeBn6yQVirEsKecVi{~ULtB20X`$m)2Cg4s!AM^65IkG!fqm82T4{7rd=-I z`}q5d9)3k{pn|teUE75Vxo-k^4j7}Qou^>+;)gMfyodg4ivoZ>I!%W824idU~g;U`Av*MixG4A;3OqU9~NjA)1|>2a)4Q zo{P>Yx(EVyyx}1q!Uf$*^b$-7bQ}*eBNamq*%p06wy`IJ{@cm&R&nxU^q0a3XiBu% z8*5$jitya2qzB&uFibRGyq`J`=z03|@B3_4p3L_J=Seh|QP zqjvF$ROu)o<*lB?+ps7V+lKNa3Bar?a}_bdo}tu_N%Ra>uv}ChM_4O3=Rc8X{h<8} zDB(3VH3bD9IPIxb(h`o4^Xam91rrj)#{8nC5H>wW`fTS|~=4-@$Jn$<THHEaaVRfbH8KyE9s?b-_d&Kp9{afZ2h1yLEG&U1C1Ba)nSeby zc)9)~I<+4KD3OBmF*peCr|dZT<6jY;R;?T)NA(1MyPY`%4j_{viW0xKTl&>9?obNMk2C)7VU-N=wL z(pU!kx2A_`pK)1zY@P3aF=*@>@%fROm+Rpj{^T<3PK)BH8S@-{8A4Ypa5_V&pJ$Ig z?vnkTmuFFjc50nl;hfC*7-9de*2L(Et995ObMA_sS&Cwmeq-SKSa*wsx#S5enu8S_ zMu_0c2O!JByd^6AI5Fpkrs4N6)}g-iksKqba6Ijb)edV5D3+-6`PYjIqQVV?rop_U zqyMA07Jsa;kdU&Q0Ae>4KASmR11%#pwE{S)t>*?0@7DIyy4`*{`{uvwGujlx3Jn+w zt&5Rnje2w|CnoQB7Zaz<&LW~0DGd^RLMnB;LwFlG9L9#7Hr~X1AeU&*eIQ8~(FbLt zrQ)%ld9*vP`9{xFc+r2$FAkHnHxS|x;>C1XjMtu$oed?weP2@|Wnf&P-s+1P!hra^ zL@xm|r2hIq=+~z3*mom?<$ceH@NWGzMFRZ(Vwnd0ukU?As{A-;gOx)qtKaEstYHgw zU-*36WWAkW!%1$1t&@(itj0P0vS`N|*ZW#5ZawX^v?#zO|0--uC5;9NXIkWM_Z>#x z4*D~Q(HQn_ti-8xy*E3vRGmcm?sLR2qD4(ZzZYWq=J@F70@xuTX4`@VstjNra2Tby zfYtOsYi6Jmh`}NkzZ1uMtJGmxLcVU|;%HQ2H;cDkuC7S!pSz-(-jui%-)depO)mWG z=n%4w4GVh4tz$r#uTRSgHRy^PoW1Q4E2;~&TiIU>aLOToTzw5sYA z*>o6wbM7;&m*AV6Mj;aGjB3Xm=XDcW8S9IhkS2uk3GZpA*3dXNH;ED-=`>lxMWiHL zTzXH71nD{t4_!KqyKN?(4m6wCjHb~h%U4uXgxWAT0?8K%ME8=GGoZ`qLxm|nFto54 zw!9Vl)CiGQ+ty@OTkYn*_>#eCBwfXn$M`s<$$mxcDZVDJaLPp)$^Ml- z-^|OWX!g$4bT%xr6yZn3E|6#HVr06*j2_*Jf%G$3-zD=SbjaW zRQcs~s!s@u;q#(zi*;G72HZ~7M@c@4pA~e8l@`Vq=&j`>lJ|Dh#!BiEv{N~D;hUSJ zeO3C83qAhgN8k*xjeC8PXASP;2Y3O{dR@T8i+!VhK2}nBITKK~cQRJZVzu)pFzZ`&Bs{)D6v_wvBj%?igo7Lk{(AuPD z*M;MijLrHvVR);{KFv!}Fz9?4f5kV8#sALS@y7UkQ>bkIIl;X*VHxI1_9gFQD8`4= zq+M_Kl~fdjdPqkJlBZr+j9V*Jm}kpkclKaNC$f2txf?959@$i{H1D-0?{JQ^yok@V zzb#0|#UU!L=4LjsDZm=XO)l`&f|%;My1QrcILra5CUj8BNl9K~#tZZ+J@-!)ot#)n z2vu@Lgr(R5cd)fA%A)M-?!z2sZuwh#UU?q1&BMCs4b zOy3TTjR7RdAuzCOgCa5r9A@?V+0vzO)Qs&FU`&2Ik{R2WnbC}vaR+IVm8>*wnp>xDSW zd-s%ueQ@mjp{lH(TLeevj2k>IJa#d&9dlH78i;{O487*&*5xJ8wEp7%%VxzldkCJ0c4GM>Jt0#sOCs?bYt8bH;O2)D%VA_ntIowdwDPV0*&Hi2kXuZ*+1{`h83&KCsZ->9WL`Xc_^nfERYkD6>1*}^Jn1q z>t$3eq--c4ZhANSMm2qzg_r+rO(j$|i0=x3#gb$U9o!roy zW7RGqM6$$P*78D+u>M_jQ`8I~Tq_DUv=3AVDuV>W{7v0e_C1zb{KKUt@Nw`DH?Nk6 zLFGI&zHC!rKmvPiIi9s}YEc04IGKm#@#?rnek;u3Q7={c>i6Eb88oTL%fs%n$QuuP zUsEVFE;ZY46P;Ul7;S|#;50Dt+25xwSug)M zS~fQAE#mFo$R<4U=xsO#-`(rva5kOM;kUxS4Hqq=!DxqYhp8r_sd4|pUFns^_dcm3 z=X?_#7%yM;Qt=XduAo@|SpJRvO2c`oUHx?9vc3wG?{Q;g35}XhZ~;=G)Fhr)wE1hD zs2p*9uAZpMP{vhAlRoCEK|=?(=f=RjooKc*la@fwBKrBN-Qj5JAnJxlGxtrYiW|Fc z*J^2j+=BH{@0nYQ8=quDO#c!6X#nEl%w%`gIha4^a3R+`Dq+vAqbU}lr>AEk#4SER zjiUwtkVR8M$aVd`)^X6q2AO;;3e-ZKlNqh5^bHDsA7i&ll~vf{ALdJKt3;^U(!WIn z{1f`2Tg?n(;7it&4)Y(rnRSzMH}^PC-<;U^#^mRI^|zv4k;hppOCO0ib>>r{@r;TU zcxmabjvM43*D8@|Kq>h^KAlN@Lk&?*(j%l9Z(sdDuVP{t*)k#SeNYxchZizXQlqNy z<)f7zBUN+bPP)YNSi?GF>YsLcvc6*fJ_N_bjXt2NJP298?AEPw%o(=t_AHc>w74hH zE71g19AY~te=1;#_Xj-N1tgp*HY2zUvnQl!Omj~8PS3SQ4O=V&%Q`Nk1M4v+?<5Kf z+<2W3B~DAbi7nwQeqOc1$C!Nj{k~{_4zrRx4FtwS31j0fMo4A#z3v4n{F}Vf%r`Sz z;&XJ|kC*yG-DtV+A!Y2VQgO*0Y~-}$p}mNCvrF?__mV*g9|C=g-GI<(`Iq&{3RNpT zkDW%vLp=oguN0PuT93h=3>^idf&frfu2(CqN-I2d^*YhMc1wuo@;jvgh}o>^QHG z^dK>JNN-9dAvHfcSyMaAN;JLUXX!2&B)|C^&3N6{;E5-{$$*}fOiLTN8<{f2@-i~+ z5zXRWD|vNeTR=Vk=zI#PN7@G6Q@E`P^dk90*6cD@zlvS9pY&^&Dm<6+63~ip_zCEd zHLr?04R>+@4)#kqeQsS+7WO=S&46KAD8-^rg75V%wNul zuTf-#4Udc}FUUP}Y>S-?C#20@AFKXJMC%=tml=oUFv??Xl+K9IC~=gF+Fya+%Q(&( z`>_ryc&pSK@M_hE*e@Z^5cG z_WQjVmn5usW0#0aROURZ(EzzUryW1?WhL1|w4_a(w**1AfzsVGKJoX{x${PDzZyC(UW? zm3mJHwE6E)BdyjSQqR-haOE>T$iP31KPw&(@Rok&^kgwWSdxe^-FLa9*xhqqdA#No9gCeLPtoUVbf0?zdlT>Xw2lpVoC}3 zKemfgUbW@jYTB8VW;*$us%M~OM#!P#t`u4ucHyHQbsi_DOMm7QF(bJ~!*3%V6=~vQ z2PF^?*k5aUkcTZVSixqZqc162F_><@D9iA1f`GXZzn}I9TR}JenWfg^s6c?7bhOk; zg9*HeZ0K(t;@&3RD5FVz6@Od1ia}b7P?kzg!)sQO28WgdZkD8xbq^?Xq2~_|;#LZ4 z`NK3n8WUf!fK&|Ic0Of@6j^EAJ-rr(fn`DP3MC*e~taG+Jt;E9;cA z^Gz?cux`K5iMUOIycSZe&Z{E`twu36k)p&8fj}7=7##MNy|6)BvM5z;@s(te^Te$I z(T+l4Kl#smZOnwu`x5qx$+!`!kJk_44aE1*$_d=gx(9HLaOPR680S;cBqXg;`nIdF zaegie%v^5g9qAg>1^gPwR$?Vx#K8^m>aJJ$r+9#1MV#;yFX&s?HXs)0Sq#-o?Ly=` zd!M(~&qiDEFHk>Vef1#9;AO+Fa*s^D5?%r$?YPWriaM7ILi@ZH*!pJZHXmsN^t-vz2n-;T~mRokp5zbr(Ihn-|yH1pM7tGpH%*&b_9JhADhkZx(Ni+Hl{U>P080)2*NR{jBzy(DzcMrI^B zy%jMmSH?hJ`Phj=0dswhLAbLRHsse3+FpOV{DX6Lqxf2RgZ8ssl;wD3Q(Hqzi+`tq zU)feaPxQepVju-yt42eT9!FcF=NLbmD81?zn`V;VMEb-55@C&)R6iRZn^VL$sMCM@ zgxWE8a}UNkI9p@v^fhKCiF7+^O-W}`n<9GeBva~n^0DW0_o@~=fiX|dYmad#=YG@u zo%5DZwjkk|Ie+_+I(7B-p#7rnOHF5|7_Iz0GvjDeT%CCTET~pvmEqBe*In}s(Ca{9 zQCHuhtcaO!b!kGDB|+AVcfv>6?Z;f)o24BM{m0px*85rMHI9$7(-T7n#->sxhX@4D zQw#ZEEiZi2o_8Al7%M)0c z#d*&wk}@Op=tqr2dVT;#guF3OF@u1u`UvI`;R;YldxHP~q&7A-I*LttT>&nOLM#?& z%+!?8VGA$XaY9BNS!Qt}RH=W)`(L-r_)`W2nTA#)S6~^D0UM3^_I#lkDpBgv*g@23 zu%g0|ujLKM*16Q2*<`XJGAT^er76jLm((P;s;;)ktgO0pym#P4FqHr8osaB`XX*jn4Kj2h@$B*=!+L4GeQtM^CyBuix(|AQq z*&`AcNvL0@QPveXm_v5PIjM7vY(M6;ewS2ou^Z&(xfLeTlzZ$CzZ*WhELRn1DU;|Z zE=J6=XoVd4#*Oa@!hK_F#C+L;l0V6cy~)LjUi|Qo_lvC9N%75+`jR1&p-xVxUZJ1Y z&cYO1<(cFT99OT#dYrp3v~{==5B}Kf^dA#TnIYLy0Ys zf-Uk9a>AV??>I^g9d^c3Hebco3yJM_)fX(4oZFd?y)b`6S?-EIqk4EfD9S}U1!iGTlOva3ic7#}Oc8-nF1hNyaZy*{MbDqOL@9e{3~Eo_^HPP)6~} zvzAr{X8GKsjz#XIE@XMAh`pwk#obd*+^$M~Z?ohuRiVY85jpe3WOjov-`~|WTC;_% zp_av8Ayj}?eSFy@%|Oj~>+z!jlb7l#t5Yhviyn`N_L*(FE%#+Yf+04TUiQBS;~jk{ zr*;9mnS@hVSP15O7!Y-9cEI#PB9VN{9&lhw{KzYS`)XRGP5KIztV39CrdF>=;ow(PYFzU&3y+K3>YcHxOsan{~YWLG1s2+F<&bhbGN&G1C zGotq@&h0A{5f32a&>Sa1@hccryDmGQ3S&^Kt&>(M8E#u^J09Pj)sZ<~vWxx0=l*1fgm1)2M!e3YI-JrV z+1z8ZYg4IdYItUnIwJZ-vtmO%LRRdP3z4sQ___7;k=EdT)92RB7!lzg=uG!<(jy<( zG~6bc?E{-`EfbUCju9}pcVJGW=9|p-S4?Qjemhmb>%-5>1|u7<1+8RBBt#yQQf)FO zLs!hW(xaS_$g{a$ax+OtCQ2rlVwG?cE2NS!mhdy zm-VD*>_xGzMPb9AO-7=`^}a{?9pg$k<-M)5b1qZa%rtUNO28P!`W;#S9>Ll0nrPmw z`RPQSWI`JgQM38Dx_2h?tN208;uo?&f_IXku4MdCuI8RB==-nW%`#<$0+|DYx@M@1 zALm3|S{z~;F%E6^I464u$@X#>vX5*oc04m|45m7HZWiI%8BGf!u*LX$7sIw_geuM*zq48HufX7P^*uB0P6-2 zqy|pl&$6Q1I<0mEfG$cSG|u@IF%|jzo#~s^M#H6%e=SptEsuAX@AX_z$trGKG5KX< zWe(*2l#dlztG6)!$4`YTu&WfNqoZZ~E%^mQCZm#bb4TH-nck1=ZZqkM&k6GvG}XRoS+rJv{JqCVH9z|-NL1I;S6YeP zBDS?!qD311Ib+AF$4242@%Viv=YE_(9tGP@d`q1oq zw@m-G^Jn;fUYy0q+w%Q+7PLfdLibzd6@D!fVwTv({@>B&@;y@4`~>50+HZvylrsYf zryfS0^bV%ggUTR>Iz;3og$4g;Tl{c)!pXpfh0o2THfq>$f6uu1hEa9sQvPJ$(qGT8 zIF{yVSyPYOg{U_yP@E$`i}S85jbR`6rUWY0y47k?EA-M@`K3ws+*)xM++GzRg-ZHXu<;ha==VV9wtKGTxX!|8FCl^5gGGbFJ&^DYb5n`XbH6Z0!OV1okXYo z?N4^A!o;P;$bH^b)U{8Kd#y259{<91>oPNIZEl>h3&3s7bsm{iyS@ajMUK znXy>h-v)7>B#R&F9=^&X=L}M7*d8bMw}CV(!n5lU=ddWdtNhk{Dza)H?qNdW3la-N zN)80z+Hl{3%%C`qWERzIvlLVTA!hCJo>l>>G{0w)HjjU)9Nv{p zTO-@>Gd%kZRRWmJlb~oP+EoOD$`gzn>8;S`5(S$fxV>t-3w2scAHNPy=+!6LXYQR>#3#A9~vb*zISc>x)KdNdY64v*d%+aLp^W_fG zv4{32Z_8&~b;kQ(hHwX^4Ad#szIdye{+dp!*3Y*EbhXwC62CH(Fj59zJjl9pG%tF@ zuAu{EsqwwA3xXQ3J*nsKxAfyMw!ry#b4iiqJkgif|7Uddu$=J~xtp5%OK? zC>+~*aIw-(I02i_6g!BP{g>aY9siV?QNoum>fv}3-ak6atl0W9sxCwtEcf4BSH`+L z`qgCm*3uF(j1GyB|1y7daRDZSTY+hY#$Er5Lt&To5pKlm426&+EGJJr8x}U+@n3D< zD_G~xlmb+Bp}y~5-`<}$3al=J^6bdN`JhRMFZz7T%?UND{2VG56Ehm*43_KX{Efhy z0qbMy4XG3JpgdcPoK7)au_8Wvqdb)TjIBtNt+6U099d zxg=spvEkazeuK$%ds@h!hr91U=C8iX3?*3MX>#)A9%6{B&9Tp={N_807z}8LuCq#t z%3e~|c3^($`|na)J@Tb14o`7%{t2OeY_-j_jh>cui?FctFoDs$SHGea zopmmnqmKg1ixsWCg{H=@1Aku|VB}xmNiY!ds%V0W-&JYsTKeQg>%)pHVRVV!r5FQa zhaZIt4Rp;^H(_p8J$pG7Ee9+fYjuChx44zC2wg@(?7UZFHQ|Gl`j24&tZdk>U zz#KqzT;)!)D(n7+u3x#0%&GHts`@e^(M-HZNU3e^;R`y)!xrrF?aBSNFO7eX`M6i0h1NFtav^or>A+v>uYRR zl~QYDMWx^_SMr9Vv1H>1W1ba<$Yv+q^aL1}{#a{mdC2BhPnth4^(5yVC?a z$1$}rZ$^}rKc_}ciG(`eM`t7C_yY&y0xNy*pK?w|RdNoz*600n@!Fr)CB&xZgfT0m zr@oJr#@Z}Deyaqt?giOYzZ;Edmj4zdQ`O_6FDR`+pcEnkPWts>BA&@-JyDmHGs!BB zww>JWXI-p2bB^Qe_4@1@6i)p-Fbu8E?W(%Wmqfj!toTlUbUh4YH@w*hd6zlg#=mwf zm?g>76hj;%EMhC)*}2c<5PqC=Wu8}ytyN5|7q%LEad-aPp>>&Bx*(=K^L1`FnkGg4 z%Y0wo*|thUv!HS&IF(?!O%Qac?KqoizGxDyd;=y^$aYf9L&bUJ=e+JvbIPxO^J%+T zrX3ESaH{qFR8}$RmL18P(ukC4sQ!@f-22l(i~rP|f{1Zk9h=?N(+Uf6Z)^plR_o01 zKFC)N@cwFqBX5N!6Xv8N0B=T>A6ywXg<-?)-a&sl51h6C%PN^zl85}XeHpn>k(0h< z(MO9BRu6{gBMv4`0P>pn)^GBgx(bRyB>f)N3I;P{o(lVYkD&(Wmt)$<_&AD3WH)S? zoVwq@&choiJR&Wq-rQvZ(_933v(~qO{fv!>xB%8EmYc2w;31WHd&CNyew4llKSNCF zB_19gF1LFd+{y_?O|nCqA9_e8-e_TCee9E@CK@mb)2S8txOg?h*4wH0 zJp{1g*Jp2hkBhV`I>CtMu4x?MHql2B7Wq5zXS?X?2ixRbd;%8YDb;>&vw9)HYl@s| z)Kw`wDVF;z`|X0+Ad0{MM9*>C&y)e2l@l@m(7t*NFz+{~{&dD>-B1K_igt3e8?EwX zsirmWo=qAAf;j?EK@j;?saMa|eeH(%@Sr3UYVL*mzNT4!_~WADvMcur2soJ0N=kY9 zo#GWFxa(Q`+Y(?QgE^X=CA@%ufG;5AX?)cO00IEIe!t>?#g{F?zPC^x4h}~uFY~Xn z$x#1w@1_6VQG_oCSUPeJ^S&~*!V=|d5KhpIn$(Iqkk_ozhNJrdwlgB9`2yr|{zv!$ zNdFS#E9!|-)dVKDNl{sTLU771S$?XFP=^VDjJbL+OaxFJi0K4_n(C{fIFLw2G3*Ie zF^@0^W#-8oOTrA*5&W}~m;*wcg8*v`yx>)Eqw8*^n7O3t4A*v)r#j zj`>i(><1Su?yx22H2WEMdG%opB$NI39-GNf z)GYBz=M_K!wHb))RW+%^zRb?wf^rP)lgtH zK$$^C$H(^{TLI^imi@nx?~gXXyU{=f_ZZM&+`+gJm&;2K>>>RB`@QC~Gc#bMksfev zg&=tcJzPyo3;g2$`P;?#uCGrf0C0?pk8k<&H57y#0ijTNoo*3g-~qFeQ#A1k&*MkJ8XL$>iq~8MkgI!dNOAAJ9F|U{DAliA92J67Xb;RUU0hrM z-hqb4o){eqWH0vaCVj+^aQB2&7sNkJlRwv*;c&6!!8Gz^y$Nz^t*#71g9H*oAj{^j z$w5@8O|pFdS2U2e%PF|g_vCY{`4;?0kOIO*GqHSFYKRFLJ1m53m!O7Uz^e2E+^ce~ zh||q=GN9T4L5qqBKm{lY=Wy8oU|3mBE+RY}OLz|Hfl73f90D*e91f?VqxPIz@iEl9HF>8O;Y)iW~^NLUHVHRD5J9 zw*qZVN5?ymvjv8MnwPyYKVs414gj?HAprpmNB~A}_X1N4um5)i^%Bx`f+=uZeQKrG z=6%@ZD~2Ex2Y}LM0ZPT{AnEexaIM$a*jV$jUI+wJT9T2a0y{f~Ml|rx46MPAxB>v- zAV0(fJn`U0+yc50Y&+(XI8|V%OUS~Aidc0cQCk-TMynP*`Uh4cxZy^CZbv1P5QsP} za{DDGyreqbrb-9FQBu?8HXnk6gMa=sopX?ld6JL22JqgAuhk^P#6an=NsW>(ii}HJ zP@`p{QE8S*tOYMFPtP$hbb_XfJw6}3B&VyGEv-hVsyf|hd*9XYyBEx^xTSM-HWm~p zrY3?Hf6gH~d(AhcLVcL6pp{L-s%qN$HC*+Ty(A}x1fO%{c8cTt+iC|E%Ol-7d6_Hn z{`rh#M-d)e?BqtLz}t!|6*&e0WAa=Ju{cAiaC)JKT)2wK)Khs&ubjyrzFBMx#u4sSp?XoP2^~DN?74GPD?39 zD}SHTo!iAu3k>P!xIEN7{j>DBMOKS{M;pqR90qtpsf~dsJ-N(iT2~JH{TH<|iTQ67 z>Uoxqh2d>SCdH!XT65YIBO{S`Ue*-oI+eMlmeF(uI?%yQ-r_!s%}6pbjLAPvMi*I! zQC6XLl-VpVUs;zdn#iq+Y3adu1%)*nesyVZtX5hrLia72y2rlOq}evcO3;pm{5?87 zMNF4Wu>Jp|H-8%!diLLc&Q-!cw`@S0uUybxK`J#MZmCH&4+?*Fab5Z;GzvO7L!jBj zwBR7pzT#6Fz9Ib|+Jt`6*kaJ|q@e_Xu>Ty2;$D6?r`1s7Z!GSPemGWk)=%`4Wi_aM z7VMQ*ehmPF2A-#^CUXPoR;P{`h2HQd3ZCgmq|@dWEp#h?7Vmcu8zQyu-*TyxL7YJz z^OxF7{OPa#?61N`(jo#ykk+1x9&dyB0%)O#^9gDXfq%7;2rgEla4FeP82Ue+wI&B? zJ8^66^mkMBIH&yhOFAOUm!a=nA~3ZD{JO|ThKJxlo6~PJ3t*YPgL4J8iBJ$px2NU8A<45-PQ$1+Ku&~6JKW> zeShN=2z@_x)z^P(+NwfD#Q5&Z`1Kt7ymc{I(%k7T1OAOQ2op=vWhg*J9QlBlhYVcr zq!tm7)GF_wNnW%_eUn;8fk8f3I%<6awliiXCXm~53d)8UP`1^rf;bx6R$?inFITK_ z@t_AtyD)BXd2h_b$e8aTPw+!kg4yv#CDIoJA%S!dmH>uD;0D_HPov{%5?k4AFs@D; zFyO%NJE_l2&P+~%7#`O}GYLsaB%Fkd46Y-&w#mz&#zr@&d$Dm&=N6$bHtyg^dsO#CYmoFWD4LJ2@ zH}L=vViT|*Fb}A21;LF931KyRqi2#kL6kw$%YpCHm2M}Rn1DT*_3K=iLr8*eMR0m& zbZ3^vGEK{pkftQoxh{3_D!q*GA1tsTtN1+zZy!RJ*up65buXjn_>xI2tjg>+RENQ& zFt{#~o^e~s2G6V%(Tf(*alnsG5xfcs_uYarH$o}pNY>)f5N+g*dIDxz%jkCQ(pS1X z%yxKXJ;x8xD_+G&Eg$hgzr)Fxup&vS+3ABnbrk`cI4h|z56zC#sbbIQ{ zAu1z84UcCz6lS<=tf7iiNllAb$mSYLIYqInRf&kfRSCEk_5-}7F0)_b54~`JCW|u? z!d<4Iv{+C)L03B})@bT!I5H8MS;)jGPC{z6^L-XMF3I?Y$!zGJ)(Dn2bfwl}xK7>i ziOkF6ZL1wE*6#cJR|MJ3Lfq=jJajzmv*E~<9LBSpPRoUk6dLG>msWUE^31{ylOoVL zv8iAu8#vt$tS^^59q6(xJ2M@TVgo3}u4GD~>t@)4jOlT&uBLDnJ{4ccjY<{Ul-9z( zmq|;TFLe)sQ!ETEqXMr6lC=GkwrNROFWxj)O2Ov{?C$V_ze$btff>$4@RnLC zzVYLijU%v8=?#{A3^|IZr`*T7CSW}jNZ%ny)D}SJ#5g8l% zrMkL=;VtqMq+k`4Qz}X3pQ5sNpGdgIKcE9;-3=sbHYF*k!S}?v z{K0gF^Kx6VTVrf2!L0tO&#wpa!J28EAgKbCMKkp)FYg)e?M``-v-?rzI52WnZyb2~hu)bJA}SUG35acSxBhju=mnHdo`sv8-( zn_t>2pCde&xBgEHSX&})#O$orHL>SzXTG+(gs2!KYFx?Ke&E(lp6a`Fvp7Lm0d8g^ zfEH{0>AcBY>AT1$q zNr!a9&>$e)F$_qFsGuOB(%m4)&`L&?7vQa)ZJ_Hq}{w^TDC*svzr3UXzLWc%x$%@iR{%5g3V3~bpqLZ;;kOGGCdmi z(^y(8#+t3OeST8QV6qwq#XL|sI6`d%iJfc-dId1jb8l5CO=zt<@vE?iP@*ayR&5F# z2+@AcN~9W`3B~h?`4t%nZh|xE9s-^Ed|qW7GNLkMEXb|ooZUXX8wsQnVt`6}r#T1>-Rh3^VDFPw&PX zWo|D&sxjDXVEVwVPVuTHudBd)60Gf}LT_HX_ zGf%qnGC?MFP``DeIl-q<9b)NO-@@CuF%%p`Bb2*y3*>{TGAlFa%Oo0|3tZXJlA4-O2B zh2lA!7d?!|YmFTp7Y?H42t&PPN^oi(wF2|azOfI3oByC z>ft9N#2MFczVas|<`a;{)4v$<=1n2-oFo{dmu+pf=AitJRj6Vpcn9C#MnE!EJqJ{G ztRor{>gJMSKlo*hZVK3Pv*m|w+&ru@E45LPA7HfCXv|2tBg0xsE~MGN64+dcp{hsB z=+u=n*(l_(lAfy+96bIWg??lGP@yXvhsN-SP!j1<@s}o0WVe&4DQK}5)=<86wjVF7 zc!*_F^itQ;W5i<1l?e44cxUHKxM+1V(f51O+$k8Dv;v%HdppVk!IN4#m+q48|5wHh+xUFbhzHt{idBm2zCLlU zJs;oNqqW_MPo9jitu#X$XSbM6Gz@n(3d3f?Ba2l%L;5zuAe+Fe03vvKpama4_D-0# z3DT4HE9^(8soQN)@|bE3RDqy`=HqgEXsx`!Os!pWH6A}BdAA9Uq>2p2rz_Q%8j1)l zJM#CO+PC;z8HUQ*acK1^&6)}wut~tY>hT(iu;AD9YHT1o7nM~$B*^wbpZMIN-BmK; zaEGlb(oU6tY0HIs9AO!iJ+Y!CIu&^pjnfjCEbHr~ahc|Ce+@bgJ@6^Ql5bs1xXI3M zu`nV3vQ(els3DR1Tg~;(g0x6Xd?c@5Oe>!CR5T*``;jDskT8I)U%PtI910?(=g5pQ0$YjN~VZ zdu_f3#VTmA*-!-wNsxCfCa2%Ge`(&mzkcO!-{xYgPcJB%Yk~%zJflUi@TAilYHLW; za&@|uYkIE%g7D2MkMQkgZ?Vs_o|SjzU(~Gk2F)&0m91Y$u4SsWmdpe`sW=bYm55M% z{OAIQt`+u{{Uu*=G?l1MPIh^M5dqrbZC1tncTX>c;LKJogZ?YXgwg#6P=vc&JCi~3 z^HnS2?g6}4V`tq3Pod0H15o)zMKKCx+0dRt@NKK&XE@pJFaD_*zbCXib197Zf_j<8 zQ$^ihFy#opv_N>lgXevm$skuC2`o5%Q>i%XM|&b)~0~XI9c@ z=_aL(_3`>Z!?5QIolBUq%BHuhI+-@|dPb(R8^RjsxhT!38o9x$eLZa;!r$iaXyU6& z(fd}K+sk=Y<)aF@Xht1+=N4e2kJ!nv%q`%>HvX!cqY|?Z=k>jZ)tVyejG>6D*ILSJ zLUeQV^=_l1y(#r8)iQX>oQxhz}# zY1=k?2cpycc|TW{se?=wdrxr>8cezkDpq&BMDm`IxuM6dg;L;e*1xU%k!X#-$W#Xj zeiLP>dU!b{qXnn!`1gvGA5aR6tyg@JlpasiFUK)f+zwG4?>K)fOl4N~>FXyoia zYXv)FYyXb5-Qtfj$5bBmrePkHjJH@!wK!^3dS>~q_Am;Jc>uJv+m936)t{)WvYVk`Aqd+&>549A zJ*IE`ot$CayU=aF>7rC*p;49U9^Jm<)amN|07{5R`NE!zyw2ODLUk@2wl%V zV*Id?<301-k*-a8{#eV7<}ky=fL_^zOO+9wCev?+RxCdG7y9kcCoiFLE4(m@Pu@PH ze`ptp&_?hEbR@tKk7#IewY~GcgX}0yD{{$>RC9&Jl|l3Urj{iZw&-hlq+H{JB+wFd4r`R&N;-m@#2;&@ZnJSzuBuU7P|Y{g;#mK2 zRO`(IRl*bk8THHEg^v>XF>OrTu%t-hQvs$(SK(DROZeea`CVQ6y->H?=X?{NRH9?m z>e%|U{R6xNI?v8+2(s#7j5Pz%BpQ-P*qz%pbD?>7e5Gq@f`?&avxg6%6pO(gP)Lf( zIi8%zUH37jGKwoI9cx=sSj_>fPC2wiJ+?dDS^G8H1oNkcMtx%4?pC_+uUhVpO3#u; zjN}eEI9&Fv%t*-+d_5~*`V7MnY!l#chO2WFQg;b61?l&|IV>6TTFm|?ikm4L8liat|UIdMU^RK@A(m+*~_ zU~JkeJmjSwY*TgHN7-YzF0C^1ySvx)L*1n%QfYN%f~;$WWfQr7eO^BG{E&fW?tlev z**OOF*qG@Tl{*(!4ypF-mtl=JI*jtV>y}6LPY3R?(AG9b>c=TH+{)-)6vh!s`3Vi~ z?01VuJ*gC2T$&Iz@r$Fo%M)<|4*R4*Q%y(YikN2vPzh8IXN=Zm#-pyBb6eI}6O^(nqh;0UG3tD;QsV=CyTpZ8@swq5a~0caOH*A`vs)P^s<1qDl*tl3>cuOI0YQtQTe-aT#c@ zj^9u6N)&T~63XYswUdl)@%1~z@X{iE9m;;7HV?>UQj_`iiZYDXuKlQIY4jR;Cp9_4*tu6PX+39 zWLF6vt+w#9u74F7xn!BME{%S~*p(iIfIS@2)33qL+ zJG8tJGvAe?YtIGd4J*cBVoKt(<1_r zWe(kC1Vd!ORVUmxOsg;fv+F~0x&7-HzT6rIbebJMNi){GtAK3LVM`0--u@poYl;+$x8YL3c#GkBkGRR^@>6s5i4;XXL3G98nfm+0IFh{e9LDCREGf^8ZpXnh#)eYLM?W5xdJ_JG)tkk3f<4EM<0@4v4&E^h&@Yv{2xwcFv zwHV4|23reiJG?9KXT2RlS(-A|uD!fL6Uk}BP!ryt|L@JXG_g+JV?8Aogt%H}mD*Px zAkvy!PWbHT(nkD;*PH&2H$+tXsSn#EZm`>Yv2;maVrXKzsa?@|!}H?GT=|{M>4q15 zZngdiABf##!|FcntNE=rUgK?hTb`K#l^98uzh}*zPxvUmc*X%s>1h_cuEOhR0 z+&%Yv7kn}?$;qP5vrS+J;wikbE5IV$$dK+WXzOP`bKW`*1E1z8{{FL!!Pjodw(*l&igHo>*bAQ?jO+`NGmCz1~!tUJRe1&&dBom5{0N ziitnhcuryk%M3hZ>9l29A8l&3wG?mLcSk!+9I*eK)Th3kWpi58)r#bIB+&UH%U&`; z`yY5{Z|CFOx(pGiK#Zbuw6iG>Q+hOej;DjE+a!k!tcvnH`JSKFSf@YDrOT;cM=ZHu zvZ8|y?T5*1)p@=wH)lG3UnUnMIHC$a0>8?Z5v7@g!#kkk0q>cQZhTMwU`b^I6_z*2$p>jA#IXr=$9Qu06CRXvwQmp1lsUfSP zBIDjKl2~io&5e~`QOkV#uh~vseoB8r=Q9x|(MJ6if4&qdR-djK`P15#WG(B^A6#Jl zWkt!uz-Xu9uu*euC2tyZP#1ulb$;$=T;$tnKWuU%cF* zdID#1eH76D^09#Li4bo8bVzTqoWUGQ_Nt>xvRN3#hX*_?($$PO)XJ=jh9k2av2#gn zsDS$fZwyGUjBl!I27XjR1g0LjQ}^faQD? zu{5PwL$19C^DsM?`1&%Nb}Riy^no~F&m-_;B==*OH385ufZ@pZ@K>KWMI zuhyRtWEEd4Q4yPrQ+8PS!yXl51nK#2i#-#+VAwho`9o3emq8+hoS#j7u|H~+k4(pB zB=^HL@+*D2hYL^SR}?0Lnt!~-z8+`NZ3&qiT@bux5mlNqMV>YN{_9fC=A}0VSNc{~ z7p2=}%W4*(Em#q&Wt+fM6 zzws_|wmmFy%#9?~XF5Z*>|wZ6JTJ4qb1U7VTWgxMq;iM!YB)WeZ{b4RHS|}CHkz+b z$o(+~h0^vG;)CTZ&f0CSBAug{vCUKD1bCqVX($5-g8t4eo4G4{5jr{cc1ySPTUd&Wd7Ez&f zH)R}pr_Q)c+DB`p;~t+`^qzJd*~?WLC&PhVVRTK$hXklXmiW+a516l1mBhz>x~y(x>9A8|Q%UVT73E{Ece1eJqd(#t zjyYt{ARk+~7Ma!~oqsC5I!){&z8!FnZ*9%2H;4J_t~$#pk!JvhVuB;8+bCVG+@o9G z!LoFMNqVA{na{0+<{lFD3$vJ{+&xgPht$v|_PI65!=r5mdz2ITwkW2Qsr6-|b?Npc zm<1fQ^;=_5@%}kft9q#09gf-)JbLzjP4H;tE8JgyIc>UEt{B$O4|!qnNWFEh0Ac-6 zv|Kya#KHNBm%rk=(ZtS2_gQzA7bn)yv(E~#Gxqb>S1}7qM2wxSnT=FFV<`4fk)g=N z&C!&B*x)>@xbVW6x;`oYdVo-rW4X`W2%WefNW6QO;yG`i%vkZxB^G}9tIW21X`)|d z6jmULXBbPC9?-?xYrU4=&Js&eW+NOaO4W(U_vY|2{`}MYKU;ImqRW9w&1WmEr_SCG zjhCJG8cfQFEFdG%W4|rNW^*Nsf)H>M}O>UTLPvX_(5MxMp1 zQ*o2V?a(+haUF<>Nw0qB28m{fnwpteUr6fJo#d@P7J94Rew%i>3PN7$h{wPWs# z&4JNslFvVNb$vMucw*(jKp4TcB4Va!u3SuwZMvKBP|A!}iqMk1{&9ScVCWp@nv-FN(D5U2+3l`(b$E`I+3`HK zd1!8}2r^p&m&-xU`RDOcJ~RD>a7f6Y@$mEn8D4%?z~`=p-rnBkX8$C!;~zjCxKthi z=0p?IEbd$Q{Ri~5T|jXNrhbvrBV_LN;?Pm=H?AqOYimM}f?_2tl|D-RhWcpT6Kj>kjueT1 z;Go@Loex0VDd4X-7&hKP7ZoC(tEH}J%M^Y_aWi-bGNDR zms}gK1ZKez*S@i-%ltu*>XOtx_AR?g?56vkz=?pD3IZ<(sKmgIRRi)Y0Knb`1yK<4 z1JhybcDYd*2N*q1Oz)s-ZZPs_;28u8Y(Xt$7sB=v(^63XcR^Sy5oNadI$UP6!h z4rVC{Bs%<#8vXca7mzUZ$l!;CA3l7L3ugqmFjP(v2IRss3MYU@xYNBA{4PcM=U5@# z(0TT9V#o%9i);uH8OgY}rkBaC1->G>4ow7d%%HLgmuC`+#$a|K&OE{du7DW!Ab&*rf?ShAk!qfeOpqkgN)h5qQ!9dnc}N(rR}yGQ;MI#HEZjAaze(FhdWW6$#c-Zy=HY zF96_5$s>}8P0x>Zzz+=-i&u2RAxrMxHe5FYfpj>^2}FVGg;eATF8Jm#3<^=I!wOFW zHVHH9O?>ukPp5i4e$7e+`NA8ch&)BcLGYn6nX5GiMlH?H<4m9g;l~}OFW1+`OCWtH zLeIJ!1dVIZxRoA8DeC~&IGk0Mc}m>%r9jf`WnpS5W9b&y6-l~o)8c%T&rNZ-3PfnY zRxMQk6N{?hDu{W4LqgbDS<{(hn-feto8uUoc8#+CR?pc6U~SvT6TCGNx^che@3S$dYIl36OoEX-jyc>>(%b01E&eoG#4BB6!5v;CIVi)02DCX7?(+x?x+ zxD2LdIjNphC$#AgwWQ_h_fy}!E;dup?OowM*^~`JQh$-pY~T`_83YZXntTR{!j6h( zx;b$v1M`CuFsUN0k|kvjN>;vqoW{KTWjjWMZJlpBSXG=%J#(kni6pfQ#ID}JpyfSu zqyfj}%xwwy7SCr`0V^Rw4&^0-@YbnXvGlH6U+#uugxIqg-6XJSiXFCpyduA&Vq`Q8 zl33lR(iLfAo^gDq86o$v1xr2YLUIZ@^ZjQPv@!_guDWi{wUa94c*?~NR+ZYy$pn)q z=beqJ46(A9vd#A|?AgASIl`AM^y))J_uCNv&g@up6`io8t%AzqkuL7*ou6O%4je5f zH<(J$xc!M;_zXh^^W_1)8+=zwAVm+p@Hd^0!mRoqC37ZEUhK1haINNBxZlo+&P zS`KRMOML?u6nV>cuM?=fBd2fTTV3>5z4zC{RsPH2{e#20g~pFe*d z2C(tznCpaOxI4Z+mPP<0GpF1maRmIUp2&!Z|FD8!8H{xxa(Gz%$L0E5vgG!p&lQvi z=dsu|>0DzNZI*u^GSziS7EDzBo&TJ{8C(Po)l@$sBAxJE*uMSmw1DTN`UkiDmLeTY zag~CCDY_GKtnV9EHJyKnU?CzP;GrM{021yLT)j9zmQ(Ub&@I4I;*_qi!t3J$1sNN< z7ksV<&}#{QmgQZ&dKKa9D4De-twd3uRk3%=+GdIg#JE0SvZb z!RRMMZsThbBcGk&Qbt@Nvhg~n5AnaV@Jq<$N$Y~WV~JDqm#?mAD=877>%i#hhD*|5 z%h*YcXgiMuOBlE)td~nEK}TLnOiIAK+ZS$UtR|F|=fE9n)n96ExDgeH^XZds(`E3{IouCBH^$3!%6knj*0aC`9VLCqLmn(Qq~N_nHp zQuUy+hGbk@?nhOp%h&JXFmf@`6bp{B@lF8B}LgFj&YKWl>y#rvoI z;1$xi4eot^eiMda@Ur$M3i3N(E0Uibw0Cx{g76gF&rtkz1T9iI;qPC7t+vf?!txSa zxB+Ks!^Q_4aE4&`**)u5s1FU}*HU^Ir3XaTXMejFDbIZ6V1FOyNye!{l_Yy1lL3vJ z;Lm!!V&TMnY%C0JBw1{s{_cqkgpd}66f&@#qa!u`}+Uw6nJ>V|E{g@>csyX+I13wgo=xc zVG;xh^tZV=vtw^LxpwFfXV0F6(*Zsn7xV!0E-u(yI^7vkLx9GG&Jv$D&AkL)=_WZj zV|Y7s4f`qgHW1BPl^q`+!wM9NHN0qOXbx1jzd?~6(C#}xzB|Et+2g}K9z2R3PGa1Q zBv!8W6Dm8D6%|W20^cLFwITQGdGYM&@$@OIGglzXY-n`{m!!M0vchLKCg%6E03^aQ zjjzX5xqS|{apePmcItk1L+@uQ+=qd0;Ooa7B`Y&i zDdF$;XX>2(w1~z5s3~ZH=-`C~3y+qmsj2U$oF{bjOzL12+2B#d@kHY`lTXk*Eq6 zOzrJ#&3-gL>TU_?bPn?q4Lw?g?*S;dEuX%OOe-vyS8hF<_&Pl;Dl80|m=F*yz>37C zfwE?JUr||kcY7OQ01IHdr%x-!l~*{1>9=433Y9gJU}9g{J$r$8s1?SX;SN}|L#50C z96Pt^lXk(#*w6XS=)}ZCSa#b!cVoPG<~ha{B7SVpW#a10Ixq9|@*Vc!A1^IgZPnU- zIa84JrtGVHo^QS*D@tB8L?Av=Mmjz+dT6*D-D$l(I8jqr*f;SNZ(R{u^SUJ*6c=L& z3;YT9ZrnXO+TVh%_81)j#Wk=xwp<^wEg5o#^hk}yI?4zo_)%1ZH*n?n%TTC+YJ%j& zVFbFxidVw>^uz~+2;m5$5j}xS`}+EN%4>X+?eNzX1dP~-#=4GbP}J5!wx;Ljovh7+ zzePo-r=|=gdmtNf)ZZ7hfyTz)KvIwT5{V`1>p8K(!^70U;0r|hcD$f=1N=Yx_K|dv z9B?gQ78o`~hd`5t%9Dcmm5Up&*o`zpB9Ud2E7KxRe;Tj9%sN#@^}|VkYEv~^&023> zR|bMTXJKW{D$h##13n0A4Vxi>WDrme$w%4@8>5CIS+)6Gi&j_G*L_ZoJm9YSCijDu zJ|rw`l-(1iQSe2dvp?>=Z&ZW05E>jjBjOiIX*)hLKKpce72utpXb)z+X^wfxPesZ3>V>9Na7MqzRy)(z{31a1a2(&fAQ + + + + + +Learning XOR: neural networks course, lesson 20 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

Learning XOR

+

You will learn

Why one neuron cannot learn XOR, and how a hidden layer trained by backpropagation does.

+

XOR is 1 when exactly one of two inputs is 1. No straight line separates the cases that give 1 from those that give 0, so a single neuron cannot learn it. A hidden layer bends the space: the spec trains a 2-8-1 network of ReLUs by backpropagation, lr 0.05, from fixed initial weights. Its loss falls from 0.8896 in epoch 1 to 1.8e-13 after 2000 epochs, and its four answers come out within 4e-7 of 0, 1, 1 and 0. The widget runs that training in your browser, from scratch for every point of the curve. The spec mlp.t27 holds the network and the test that it learns.

+

Try it

Drag the epochs back to 100 and read the four answers; then find the epoch where the curve stops falling.

+

Open the interactive lesson →

+
XOR: a network learns what one neuron cannot
XOR: a network learns what one neuron cannot ↗
+

A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders.

+

specs/ml/pathway/mlp.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// ReLU activation for hidden layers | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward computed the hidden layer and wrote it into `output` (the
+// second layer never ran); init called an undeclared `alloc_f32`; the tests
+// called undeclared `create_test_*` helpers; and the invariants asserted `true`.
+// The MLP is now two layers, h = relu(W1 x + b1) and y = W2 h + b2, over buffers
+// the caller owns. train_step adds backpropagation with an SGD update, and the
+// tests train the network on XOR, which no single linear layer can fit.
+
+module Mlp;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const MNIST_INPUT_SIZE : u32 = 784;
+    const MNIST_OUTPUT_SIZE : u32 = 10;
+    const DEFAULT_HIDDEN_SIZE : u32 = 128;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const MLPConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+        output_size : u32,
+    };
+
+    pub const MLPState = struct {
+        w1 : []f32,
+        b1 : []f32,
+        w2 : []f32,
+        b2 : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // One dense layer: out[o] = sum_i w[o * n_in + i] in[i] + b[o], relu when asked
+    fn layer(input: []const f32, w: []const f32, b: []const f32, n_in: u32, n_out: u32, relu: bool, out: []f32) -> void {
+        var o : usize = 0;
+        while (o < n_out) {
+            var sum : f32 = b[o];
+            var i : usize = 0;
+            while (i < n_in) {
+                sum = sum + w[o * n_in + i] * input[i];
+                i = i + 1;
+            }
+            if (relu and sum < 0.0) {
+                sum = 0.0;
+            }
+            out[o] = sum;
+            o = o + 1;
+        }
+    }
+
+    // h = relu(W1 x + b1) into `hidden`, y = W2 h + b2 into `output`
+    fn forward(input: []const f32, state: MLPState, hidden: []f32, output: []f32, config: MLPConfig) -> void {
+        layer(input, state.w1, state.b1, config.input_size, config.hidden_size, true, hidden);
+        layer(hidden, state.w2, state.b2, config.hidden_size, config.output_size, false, output);
+    }
+
+    // He-scaled deterministic init: w in [-1, 1) sqrt(2 / fan_in) from a fixed hash of the
+    // index (salt tells the layers apart); every bias 0
+    fn init_weights(w: []f32, fan_in: u32, salt: usize) -> void {
+        const scale : f32 = sqrt(2.0 / @as(f32, @floatFromInt(fan_in)));
+        var k : usize = 0;
+        while (k < w.len) {
+            const h : u32 = @as(u32, @intCast(((k + salt) * 2654435761) % 1000));
+            w[k] = (@as(f32, @floatFromInt(h)) / 500.0 - 1.0) * scale;
+            k = k + 1;
+        }
+    }
+
+    fn zero(v: []f32) -> void {
+        var k : usize = 0;
+        while (k < v.len) {
+            v[k] = 0.0;
+            k = k + 1;
+        }
+    }
+
+    fn init(state: MLPState, config: MLPConfig) -> void {
+        init_weights(state.w1, config.input_size, 1);
+        zero(state.b1);
+        init_weights(state.w2, config.hidden_size, 7);
+        zero(state.b2);
+    }
+
+    // One SGD step on the loss 0.5 * sum_o (y_o - t_o)^2; returns the loss before the step.
+    //   d2_o = y_o - t_o                                   (output error)
+    //   d1_i = [z_i > 0] sum_o W2[o][i] d2_o                (backpropagated through relu)
+    //   W2 -= lr d2 h^T, b2 -= lr d2;  W1 -= lr d1 x^T, b1 -= lr d1
+    fn train_step(input: []const f32, target: []const f32, state: MLPState, hidden: []f32, delta: []f32, output: []f32, lr: f32, config: MLPConfig) -> f32 {
+        forward(input, state, hidden, output, config);
+        var loss : f32 = 0.0;
+        var o : usize = 0;
+        while (o < config.output_size) {
+            const e = output[o] - target[o];
+            loss = loss + 0.5 * e * e;
+            o = o + 1;
+        }
+        var i : usize = 0;
+        while (i < config.hidden_size) {
+            var back : f32 = 0.0;
+            if (hidden[i] > 0.0) {
+                o = 0;
+                while (o < config.output_size) {
+                    back = back + state.w2[o * config.hidden_size + i] * (output[o] - target[o]);
+                    o = o + 1;
+                }
+            }
+            delta[i] = back;
+            i = i + 1;
+        }
+        o = 0;
+        while (o < config.output_size) {
+            const d2 = output[o] - target[o];
+            i = 0;
+            while (i < config.hidden_size) {
+                state.w2[o * config.hidden_size + i] = state.w2[o * config.hidden_size + i] - lr * d2 * hidden[i];
+                i = i + 1;
+            }
+            state.b2[o] = state.b2[o] - lr * d2;
+            o = o + 1;
+        }
+        i = 0;
+        while (i < config.hidden_size) {
+            var j : usize = 0;
+            while (j < config.input_size) {
+                state.w1[i * config.input_size + j] = state.w1[i * config.input_size + j] - lr * delta[i] * input[j];
+                j = j + 1;
+            }
+            state.b1[i] = state.b1[i] - lr * delta[i];
+            i = i + 1;
+        }
+        return loss;
+    }
+
+    fn mnist() -> MLPConfig {
+        return MLPConfig{ .input_size = MNIST_INPUT_SIZE, .hidden_size = DEFAULT_HIDDEN_SIZE, .output_size = MNIST_OUTPUT_SIZE };
+    }
+
+    // which: 0 = output[index], 1 = min over every output, 2 = number of outputs written,
+    // on the MNIST shape with input pixel k = (k % 7) / 7
+    fn mnist_forward(which: u8, index: usize) -> f32 {
+        var w1 : [784 * 128]f32 = undefined;
+        var b1 : [128]f32 = undefined;
+        var w2 : [128 * 10]f32 = undefined;
+        var b2 : [10]f32 = undefined;
+        const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 };
+        init(state, mnist());
+        var input : [784]f32 = undefined;
+        var k : usize = 0;
+        while (k < 784) {
+            input[k] = @as(f32, @floatFromInt(k % 7)) / 7.0;
+            k = k + 1;
+        }
+        var hidden : [128]f32 = undefined;
+        var output : [11]f32 = [-99.0] ** 11;
+        forward(&input, state, &hidden, &output, mnist());
+        if (which == 0) {
+            return output[index];
+        }
+        var min_h : f32 = hidden[0];
+        var written : f32 = 0.0;
+        k = 0;
+        while (k < 128) {
+            min_h = @min(min_h, hidden[k]);
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 11) {
+            if (output[k] != -99.0) {
+                written = written + 1.0;
+            }
+            k = k + 1;
+        }
+        if (which == 1) {
+            return min_h;
+        }
+        return written;
+    }
+
+    // which: 0 = w1.len written by init, 1 = b1[0], 2 = b2[0], 3 = largest |w1|
+    fn mnist_init(which: u8) -> f32 {
+        var w1 : [784 * 128]f32 = [9.0] ** (784 * 128);
+        var b1 : [128]f32 = [9.0] ** 128;
+        var w2 : [128 * 10]f32 = [9.0] ** (128 * 10);
+        var b2 : [10]f32 = [9.0] ** 10;
+        init(MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, mnist());
+        var written : f32 = 0.0;
+        var largest : f32 = 0.0;
+        var k : usize = 0;
+        while (k < w1.len) {
+            if (w1[k] != 9.0) {
+                written = written + 1.0;
+            }
+            largest = @max(largest, @abs(w1[k]));
+            k = k + 1;
+        }
+        if (which == 0) {
+            return written;
+        }
+        if (which == 1) {
+            return b1[0];
+        }
+        if (which == 2) {
+            return b2[0];
+        }
+        return largest;
+    }
+
+    // Train a 2-8-1 network on XOR for `epochs` passes over the four cases.
+    // which: 0 = total loss of the first epoch, 1 = total loss of the last epoch,
+    // 2 + c = the trained network's output for case c
+    fn xor(epochs: u32, which: usize) -> f32 {
+        const cfg = MLPConfig{ .input_size = 2, .hidden_size = 8, .output_size = 1 };
+        var w1 : [16]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [8]f32 = undefined;
+        var b2 : [1]f32 = undefined;
+        const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 };
+        init(state, cfg);
+        const xs : [8]f32 = [0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0];
+        const ts : [4]f32 = [0.0, 1.0, 1.0, 0.0];
+        var hidden : [8]f32 = undefined;
+        var delta : [8]f32 = undefined;
+        var output : [1]f32 = undefined;
+        var first : f32 = 0.0;
+        var last : f32 = 0.0;
+        var e : u32 = 0;
+        while (e < epochs) {
+            var total : f32 = 0.0;
+            var c : usize = 0;
+            while (c < 4) {
+                total = total + train_step(xs[c * 2 .. c * 2 + 2], ts[c .. c + 1], state, &hidden, &delta, &output, 0.05, cfg);
+                c = c + 1;
+            }
+            if (e == 0) {
+                first = total;
+            }
+            last = total;
+            e = e + 1;
+        }
+        if (which == 0) {
+            return first;
+        }
+        if (which == 1) {
+            return last;
+        }
+        forward(xs[(which - 2) * 2 .. (which - 2) * 2 + 2], state, &hidden, &output, cfg);
+        return output[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // 784 -> 128 -> 10: exactly the 10 outputs are written, the 11th slot is untouched
+    test forward_output_size
+        given written = mnist_forward(2, 0)
+        when spare = mnist_forward(0, 10)
+        then written == 10.0 and spare == -99.0
+
+    // The hidden layer is relu, so no hidden unit is negative
+    test forward_relu_activation
+        given min_hidden = mnist_forward(1, 0)
+        then min_hidden >= 0.0
+
+    // init writes every one of the 784 * 128 first-layer weights, each within sqrt(2 / 784) = 0.05051
+    test init_allocation_sizes
+        given written = mnist_init(0)
+        when largest = mnist_init(3)
+        then written == 100352.0 and largest <= 0.0506 and largest > 0.0
+
+    test init_bias_initialization
+        given b1 = mnist_init(1)
+        when b2 = mnist_init(2)
+        then b1 == 0.0 and b2 == 0.0
+
+    // Backpropagation learns XOR: the loss falls by more than 100x, and each output is within 0.1
+    test train_step_learns_xor
+        given first = xor(2000, 0)
+        when last = xor(2000, 1)
+        then last < first / 100.0 and @abs(xor(2000, 2)) < 0.1 and @abs(xor(2000, 3) - 1.0) < 0.1 and @abs(xor(2000, 4) - 1.0) < 0.1 and @abs(xor(2000, 5)) < 0.1
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input_size == MNIST_INPUT_SIZE (784)
+    invariant mlp_constraint_0
+        assert mnist().input_size == 784
+
+    // output_size == MNIST_OUTPUT_SIZE (10)
+    invariant mlp_constraint_1
+        assert mnist().output_size == 10
+
+    // hidden_size > 0
+    invariant mlp_constraint_2
+        assert mnist().hidden_size > 0
+
+    // w1.size() == input_size * hidden_size
+    invariant mlp_constraint_3
+        assert mnist().input_size * mnist().hidden_size == 100352
+
+    // w2.size() == hidden_size * output_size
+    invariant mlp_constraint_4
+        assert mnist().hidden_size * mnist().output_size == 1280
+
+    // b1.size() == hidden_size
+    invariant mlp_constraint_5
+        assert DEFAULT_HIDDEN_SIZE == 128
+
+    // b2.size() == output_size
+    invariant mlp_constraint_6
+        assert MNIST_OUTPUT_SIZE == 10
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/lstm-gates/card.png b/apps/website/public/learn/lstm-gates/card.png new file mode 100644 index 0000000000000000000000000000000000000000..276f007712fbfc5189874accdde941c937e4c450 GIT binary patch literal 54767 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�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 LD_ZzM-{=1Ukyf-V literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/lstm-gates/index.html b/apps/website/public/learn/lstm-gates/index.html new file mode 100644 index 0000000000..0641a1b2e3 --- /dev/null +++ b/apps/website/public/learn/lstm-gates/index.html @@ -0,0 +1,400 @@ + + + + + + +LSTM gates: neural networks course, lesson 23 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

LSTM gates

+

You will learn

How the forget, input and output gates of an LSTM decide what the cell keeps, writes and shows.

+

An LSTM cell keeps a separate memory c and three gates, each a sigmoid between 0 and 1: forget scales the old memory, input lets in new content g, and output decides how much of the memory to show. c' = f c + i g and h' = o tanh(c'). In the spec's fixture every weight is 0, so each gate is the sigmoid of its bias: with the forget gate at 0.9975 and the input gate at 0.0025, a memory of 1 comes out as 0.9975, and the output is 0.7587. Because c passes through with only a multiply by f, its gradient survives many steps too. The spec lstm_single.t27 computes the cell.

+

Try it

Load Remember and then Forget and compare the new memory; then write with the input gate open.

+

Open the interactive lesson →

+
LSTM gates: how a cell decides what to keep
LSTM gates: how a cell decides what to keep ↗
+

Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate.

+

specs/ml/recurrent/lstm_single.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// LSTM solves vanishing gradient problem | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: called `@sigmoid` and `@tanh`, which Zig does not have; each gate weight
+// was one number per INPUT, indexed `i % hidden_size`, so it was not an LSTM; and
+// every test asserted `true`. Now each gate has its own matrices, W_x
+// (hidden x input) and W_h (hidden x hidden), and a bias:
+//   i = s(z_i), f = s(z_f), g = tanh(z_g), o = s(z_o),  z = W_x x + W_h h + b
+//   c' = f c + i g,  h' = o tanh(c')
+// backward gives every gradient of one step, and the tests check it against finite
+// differences.
+
+module LstmCell;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const FORGET_BIAS_INIT : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const LSTMConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+    };
+
+    pub const LSTMState = struct {
+        h : []f32,
+        c : []f32,
+    };
+
+    pub const LSTMWeights = struct {
+        W_ii : []f32,
+        W_hi : []f32,
+        b_i : []f32,
+        W_if : []f32,
+        W_hf : []f32,
+        b_f : []f32,
+        W_ig : []f32,
+        W_hg : []f32,
+        b_g : []f32,
+        W_io : []f32,
+        W_ho : []f32,
+        b_o : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn sigmoid(z: f32) -> f32 {
+        return 1.0 / (1.0 + exp(-z));
+    }
+
+    // Pre-activation of one gate for hidden unit u: W_x[u] . x + W_h[u] . h + b[u]
+    fn pre(w_x: []const f32, w_h: []const f32, b: []const f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig) -> f32 {
+        var z : f32 = b[u];
+        var j : usize = 0;
+        while (j < config.input_size) {
+            z = z + w_x[u * config.input_size + j] * x[j];
+            j = j + 1;
+        }
+        var k : usize = 0;
+        while (k < config.hidden_size) {
+            z = z + w_h[u * config.hidden_size + k] * h[k];
+            k = k + 1;
+        }
+        return z;
+    }
+
+    fn forward(input: []const f32, state: LSTMState, weights: LSTMWeights, output_state: LSTMState, config: LSTMConfig) -> void {
+        var u : usize = 0;
+        while (u < config.hidden_size) {
+            const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config));
+            const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config));
+            const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config));
+            const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config));
+            output_state.c[u] = fg * state.c[u] + ig * gg;
+            output_state.h[u] = og * tanh(output_state.c[u]);
+            u = u + 1;
+        }
+    }
+
+    // Adds dz * (x, h, 1) into one gate's weight gradients, and dz * W into grad_input / grad_state.h
+    fn spread(dz: f32, w_x: []const f32, w_h: []const f32, gw_x: []f32, gw_h: []f32, gb: []f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig, grad_input: []f32, grad_h: []f32) -> void {
+        var j : usize = 0;
+        while (j < config.input_size) {
+            gw_x[u * config.input_size + j] = gw_x[u * config.input_size + j] + dz * x[j];
+            grad_input[j] = grad_input[j] + dz * w_x[u * config.input_size + j];
+            j = j + 1;
+        }
+        var k : usize = 0;
+        while (k < config.hidden_size) {
+            gw_h[u * config.hidden_size + k] = gw_h[u * config.hidden_size + k] + dz * h[k];
+            grad_h[k] = grad_h[k] + dz * w_h[u * config.hidden_size + k];
+            k = k + 1;
+        }
+        gb[u] = gb[u] + dz;
+    }
+
+    // One step back. grad_output = dL/dh', grad_cell = dL/dc' from later steps. Writes
+    // dL/dx, dL/dh, dL/dc and ADDS the weight gradients into grad_weights.
+    //   do = dh' tanh(c');  dc = dh' o (1 - tanh^2 c') + grad_cell
+    //   dz_o = do o (1 - o), dz_f = dc c f (1 - f), dz_i = dc g i (1 - i), dz_g = dc i (1 - g^2)
+    //   dL/dc = dc f
+    fn backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, config: LSTMConfig, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void {
+        var j : usize = 0;
+        while (j < config.input_size) {
+            grad_input[j] = 0.0;
+            j = j + 1;
+        }
+        var u : usize = 0;
+        while (u < config.hidden_size) {
+            grad_state.h[u] = 0.0;
+            u = u + 1;
+        }
+        u = 0;
+        while (u < config.hidden_size) {
+            const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config));
+            const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config));
+            const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config));
+            const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config));
+            const c_new = fg * state.c[u] + ig * gg;
+            const tc = tanh(c_new);
+            const dc = grad_output[u] * og * (1.0 - tc * tc) + grad_cell[u];
+            const dz_o = grad_output[u] * tc * og * (1.0 - og);
+            const dz_f = dc * state.c[u] * fg * (1.0 - fg);
+            const dz_i = dc * gg * ig * (1.0 - ig);
+            const dz_g = dc * ig * (1.0 - gg * gg);
+            grad_state.c[u] = dc * fg;
+            spread(dz_i, weights.W_ii, weights.W_hi, grad_weights.W_ii, grad_weights.W_hi, grad_weights.b_i, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_f, weights.W_if, weights.W_hf, grad_weights.W_if, grad_weights.W_hf, grad_weights.b_f, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_g, weights.W_ig, weights.W_hg, grad_weights.W_ig, grad_weights.W_hg, grad_weights.b_g, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_o, weights.W_io, weights.W_ho, grad_weights.W_io, grad_weights.W_ho, grad_weights.b_o, input, state.h, u, config, grad_input, grad_state.h);
+            u = u + 1;
+        }
+    }
+
+    // The fixture: input 3, hidden 2. All 48 weights live in one buffer, per gate
+    // W_x (6), W_h (4), b (2), in the gate order i, f, g, o.
+    fn cfg() -> LSTMConfig {
+        return LSTMConfig{ .input_size = 3, .hidden_size = 2 };
+    }
+
+    fn weights_of(w: []f32) -> LSTMWeights {
+        return LSTMWeights{
+            .W_ii = w[0..6], .W_hi = w[6..10], .b_i = w[10..12],
+            .W_if = w[12..18], .W_hf = w[18..22], .b_f = w[22..24],
+            .W_ig = w[24..30], .W_hg = w[30..34], .b_g = w[34..36],
+            .W_io = w[36..42], .W_ho = w[42..46], .b_o = w[46..48],
+        };
+    }
+
+    // Deterministic weights in [-0.5, 0.5]; the forget biases start at FORGET_BIAS_INIT
+    fn fill(w: []f32) -> void {
+        var k : usize = 0;
+        while (k < 48) {
+            w[k] = @as(f32, @floatFromInt((k * 7 + 3) % 11)) / 10.0 - 0.5;
+            k = k + 1;
+        }
+        w[22] = FORGET_BIAS_INIT;
+        w[23] = FORGET_BIAS_INIT;
+    }
+
+    // L = 0.5 h'_0 - 0.3 h'_1 + 0.2 c'_0 + 0.1 c'_1 after one step, with one input, one h or
+    // one c entry moved by `delta` (which: 0 = none, 1 + j = x_j, 4 + k = h_k, 6 + k = c_k,
+    // 8 = b_f[1])
+    fn loss(which: usize, delta: f32) -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        var x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        if (which >= 1 and which <= 3) {
+            x[which - 1] = x[which - 1] + delta;
+        }
+        if (which >= 4 and which <= 5) {
+            h[which - 4] = h[which - 4] + delta;
+        }
+        if (which >= 6 and which <= 7) {
+            c[which - 6] = c[which - 6] + delta;
+        }
+        if (which == 8) {
+            w[23] = w[23] + delta;
+        }
+        var h_out : [2]f32 = [0.0] ** 2;
+        var c_out : [2]f32 = [0.0] ** 2;
+        forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg());
+        return 0.5 * h_out[0] - 0.3 * h_out[1] + 0.2 * c_out[0] + 0.1 * c_out[1];
+    }
+
+    // The analytic gradient of that loss, same `which` numbering
+    fn grad(which: usize) -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        const grad_output : [2]f32 = [0.5, -0.3];
+        const grad_cell : [2]f32 = [0.2, 0.1];
+        var gx : [3]f32 = [0.0] ** 3;
+        var gh : [2]f32 = [0.0] ** 2;
+        var gc : [2]f32 = [0.0] ** 2;
+        var gw : [48]f32 = [0.0] ** 48;
+        backward(&grad_output, &grad_cell, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw));
+        if (which >= 1 and which <= 3) {
+            return gx[which - 1];
+        }
+        if (which >= 4 and which <= 5) {
+            return gh[which - 4];
+        }
+        if (which >= 6 and which <= 7) {
+            return gc[which - 6];
+        }
+        return gw[23];
+    }
+
+    // Sum of |every gradient| when grad_output and grad_cell are both 0
+    fn zero_upstream_total() -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        const zeros : [2]f32 = [0.0, 0.0];
+        var gx : [3]f32 = [0.0] ** 3;
+        var gh : [2]f32 = [0.0] ** 2;
+        var gc : [2]f32 = [0.0] ** 2;
+        var gw : [48]f32 = [0.0] ** 48;
+        backward(&zeros, &zeros, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw));
+        var total : f32 = @abs(gx[0]) + @abs(gx[1]) + @abs(gx[2]) + @abs(gh[0]) + @abs(gh[1]) + @abs(gc[0]) + @abs(gc[1]);
+        var k : usize = 0;
+        while (k < 48) {
+            total = total + @abs(gw[k]);
+            k = k + 1;
+        }
+        return total;
+    }
+
+    fn slope(which: usize) -> f32 {
+        return (loss(which, 0.001) - loss(which, -0.001)) / 0.002;
+    }
+
+    // which: 0 = h'_0, 1 = c'_0 for a 1-unit cell with every weight 0 and the given biases
+    fn bias_only(b_i: f32, b_f: f32, b_g: f32, b_o: f32, c_prev: f32, which: u8) -> f32 {
+        var w : [48]f32 = [0.0] ** 48;
+        w[10] = b_i;
+        w[22] = b_f;
+        w[34] = b_g;
+        w[46] = b_o;
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.0, 0.0];
+        var c : [2]f32 = [c_prev, 0.0];
+        var h_out : [2]f32 = [9.0] ** 2;
+        var c_out : [2]f32 = [9.0] ** 2;
+        forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg());
+        if (which == 0) {
+            return h_out[0];
+        }
+        return c_out[0];
+    }
+
+    fn valid_input() -> usize {
+        return cfg().input_size;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // All weights 0: every gate is s(0) = 0.5 or tanh(0) = 0, so c' = 0.5 c and h' = 0.5 tanh(c')
+    test forward_basic_case
+        given c_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 1)
+        when h_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 0)
+        then @abs(c_new - 0.4) < 0.000001 and @abs(h_new - 0.5 * tanh(c_new)) < 0.000001 and @abs(h_new - 0.1899745) < 0.000001
+
+    // A closed forget gate (b_f = -30) erases the old cell; an open one (b_f = 30) keeps it
+    test forward_basic_lstm
+        given erased = bias_only(0.0, -30.0, 0.0, 0.0, 0.8, 1)
+        when kept = bias_only(-30.0, 30.0, 0.0, 0.0, 0.8, 1)
+        then @abs(erased) < 0.000001 and @abs(kept - 0.8) < 0.000001
+
+    // A closed input gate and forget gate leave c' = 0, so h' = 0 whatever the output gate does
+    test forward_with_empty_input
+        given h_new = bias_only(-30.0, -30.0, 1.0, 30.0, 0.8, 0)
+        then @abs(h_new) < 0.000001
+
+    // dL/dx_j against central differences
+    test backward_basic_case
+        given g0 = grad(1)
+        when g2 = grad(3)
+        then @abs(g0 - slope(1)) < 0.0005 and @abs(grad(2) - slope(2)) < 0.0005 and @abs(g2 - slope(3)) < 0.0005
+
+    // dL/dh_k, dL/dc_k and dL/db_f[1] against central differences
+    test backward_basic_lstm
+        given gh0 = grad(4)
+        when gc1 = grad(7)
+        then @abs(gh0 - slope(4)) < 0.0005 and @abs(grad(5) - slope(5)) < 0.0005 and @abs(grad(6) - slope(6)) < 0.0005 and @abs(gc1 - slope(7)) < 0.0005 and @abs(grad(8) - slope(8)) < 0.0005
+
+    // With no upstream gradient nothing flows back
+    test backward_with_empty_grad
+        given total = zero_upstream_total()
+        then total == 0.0 and @abs(grad(1)) > 0.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.size() == config.input_size
+    invariant lstm_cell_constraint_0
+        assert valid_input() == 3
+
+    // state.h.size() == config.hidden_size
+    invariant lstm_cell_constraint_1
+        assert cfg().hidden_size == 2
+
+    // state.c.size() == config.hidden_size; the forget bias starts open
+    invariant lstm_cell_constraint_2
+        assert FORGET_BIAS_INIT > 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/max-pooling/card.png b/apps/website/public/learn/max-pooling/card.png new file mode 100644 index 0000000000000000000000000000000000000000..31fdd8fd8025fa97e01df4d36ebd0a3ac5e14a7d GIT binary patch literal 46254 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 LD~Oeg7zX?=%Hq&* literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/max-pooling/index.html b/apps/website/public/learn/max-pooling/index.html new file mode 100644 index 0000000000..714ae245ba --- /dev/null +++ b/apps/website/public/learn/max-pooling/index.html @@ -0,0 +1,222 @@ + + + + + + +Max pooling: neural networks course, lesson 11 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Max pooling

+

You will learn

What max pooling keeps, where it remembers taking it from, and where the gradient goes.

+

Max pooling keeps the largest value of each window and drops the rest, so the network cares less about exactly where a feature sits. On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2, taken from cells 5, 6, 13 and 11. Overlapping 3 x 3 windows with stride 1 keep 8, 8, 9 and 9. In the backward pass each window's whole gradient goes to its maximum: gradients 1, 2, 3 and 4 land on cells 5, 6, 13 and 11, and every other cell gets 0. The spec maxpool2d_layer.t27 computes the outputs, their positions and the gradient.

+

Try it

Switch to 3 x 3 windows and find the cell two outputs share; then turn on the gradient for 2 x 2 windows.

+

Open the interactive lesson →

+
Max pooling: what a network keeps when it shrinks a picture
Max pooling: what a network keeps when it shrinks a picture ↗
+

Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell.

+

specs/ml/layers/maxpool2d_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Reduce spatial dimensions | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward and backward compared two values and threw them away
+// (placeholders), and every test asserted `result != undefined`. Max pooling now
+// runs over one H x W channel (row-major) with a k x k window and a stride. It
+// records each window's argmax, and backward sends each gradient back to that
+// element only. Padding and dilation are carried in the config but not read: the
+// layer assumes padding 0 and dilation 1.
+
+module Maxpool2d;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const MaxPool2DConfig = struct {
+        kernel_size : u32,
+        stride : u32,
+        padding : u32,
+        dilation : u32,
+        return_indices : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Output side for an input side n: (n - k) / stride + 1
+    fn out_size(n: u32, config: MaxPool2DConfig) -> u32 {
+        return (n - config.kernel_size) / config.stride + 1;
+    }
+
+    // output[oy][ox] = max of the k x k window at (oy * stride, ox * stride);
+    // indices[oy][ox] = the flat input index that held it
+    fn forward(input: []const f32, height: u32, width: u32, config: MaxPool2DConfig, output: []f32, indices: []u32) -> void {
+        const oh = out_size(height, config);
+        const ow = out_size(width, config);
+        var oy : u32 = 0;
+        while (oy < oh) {
+            var ox : u32 = 0;
+            while (ox < ow) {
+                var best_index : u32 = (oy * config.stride) * width + ox * config.stride;
+                var ky : u32 = 0;
+                while (ky < config.kernel_size) {
+                    var kx : u32 = 0;
+                    while (kx < config.kernel_size) {
+                        const idx : u32 = (oy * config.stride + ky) * width + ox * config.stride + kx;
+                        if (input[idx] > input[best_index]) {
+                            best_index = idx;
+                        }
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                output[oy * ow + ox] = input[best_index];
+                indices[oy * ow + ox] = best_index;
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+    }
+
+    // grad_input[indices[o]] += grad_output[o]; every other input gets 0
+    fn backward(grad_output: []const f32, indices: []const u32, grad_input: []f32) -> void {
+        var i : usize = 0;
+        while (i < grad_input.len) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var o : usize = 0;
+        while (o < grad_output.len) {
+            grad_input[indices[o]] = grad_input[indices[o]] + grad_output[o];
+            o = o + 1;
+        }
+    }
+
+    fn cfg(kernel: u32, stride: u32) -> MaxPool2DConfig {
+        return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true };
+    }
+
+    // The 4 x 4 fixture
+    //    1  2  5  6
+    //    3  4  8  7
+    //    0 -1 -3 -2
+    //   -4  9 -6 -5
+    fn pool_at(kernel: u32, stride: u32, which: u8, index: usize) -> f32 {
+        const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0];
+        var output : [9]f32 = [0.0] ** 9;
+        var indices : [9]u32 = [0] ** 9;
+        forward(&input, 4, 4, cfg(kernel, stride), &output, &indices);
+        if (which == 0) {
+            return output[index];
+        }
+        return @as(f32, @floatFromInt(indices[index]));
+    }
+
+    // 2 x 2, stride 2, gradients (1, 2, 3, 4) for the four windows; grad_input[index]
+    fn backward_at(index: usize) -> f32 {
+        const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0];
+        var output : [4]f32 = [0.0] ** 4;
+        var indices : [4]u32 = [0] ** 4;
+        forward(&input, 4, 4, cfg(2, 2), &output, &indices);
+        const grad_output : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var grad_input : [16]f32 = [9.0] ** 16;
+        backward(&grad_output, &indices, &grad_input);
+        return grad_input[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // 2 x 2, stride 2: windows' maxima are 4, 8, 9, -2
+    test forward_basic_case
+        given first = pool_at(2, 2, 0, 0)
+        when last = pool_at(2, 2, 0, 3)
+        then first == 4.0 and pool_at(2, 2, 0, 1) == 8.0 and pool_at(2, 2, 0, 2) == 9.0 and last == -2.0
+
+    // The argmax indices: 4 at 5, 8 at 6, 9 at 13, -2 at 11
+    test forward_max_finding
+        given first = pool_at(2, 2, 1, 0)
+        when third = pool_at(2, 2, 1, 2)
+        then first == 5.0 and pool_at(2, 2, 1, 1) == 6.0 and third == 13.0 and pool_at(2, 2, 1, 3) == 11.0
+
+    // 3 x 3, stride 1 gives a 2 x 2 output whose windows overlap
+    test forward_overlapping_windows
+        given first = pool_at(3, 1, 0, 0)
+        when last = pool_at(3, 1, 0, 3)
+        then first == 8.0 and pool_at(3, 1, 0, 1) == 8.0 and pool_at(3, 1, 0, 2) == 9.0 and last == 9.0
+
+    test backward_basic_case
+        given at_max = backward_at(5)
+        when elsewhere = backward_at(0)
+        then at_max == 1.0 and elsewhere == 0.0
+
+    // Each window's gradient lands on its argmax only: the sum is conserved
+    test backward_gradient_propagation
+        given total = backward_at(5) + backward_at(6) + backward_at(13) + backward_at(11)
+        when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15)
+        then total == 10.0 and others == 0.0 and backward_at(13) == 3.0
+
+    invariant maxpool_output_size_formula
+        assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/mean-squared-error/card.png b/apps/website/public/learn/mean-squared-error/card.png new file mode 100644 index 0000000000000000000000000000000000000000..683b8e61255386e581b19b393bea1aa996cf133a GIT binary patch literal 49431 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 %yrP)^?Q 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 QIli8; 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 a4i1gE + + + + + +Mean squared error: neural networks course, lesson 13 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Mean squared error

+

You will learn

How MSE turns every miss into one number, why it chases large errors, and where its gradient points.

+

A loss turns all the misses of a model into one number to push down. Mean squared error averages the squared misses: predictions 1.5, 2 and 2 against targets 1, 2 and 3 cost (0.25 + 0 + 1) / 3 = 0.4167. Squaring makes a miss of 2 cost 4 times a miss of 1, so MSE chases large errors. Its gradient for each prediction is 2 (p - t) / n, here 0.333, 0 and -0.667: each prediction is pushed back toward its target. As a function of one prediction the loss is a parabola, a bowl with one bottom. The spec mse_loss.t27 computes the loss and the gradient.

+

Try it

Move prediction 2 onto its target and read the loss; then drag along the bowl and find its bottom.

+

Open the interactive lesson →

+
Mean squared error: how wrong a guess is, as one number
Mean squared error: how wrong a guess is, as one number ↗
+

Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target.

+

specs/ml/loss/mse_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Penalizes large errors more heavily | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/mse_loss.tri: the port kept only
+// the first parameter and returned void, so forward computed a value and
+// threw it away, and every test asserted `result != undefined`.
+
+module MseLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    // reduction: "mean", "sum" or "none" (from the .tri). forward below is the
+    // .tri's mean; the field is carried, not yet read.
+    pub const MSELossConfig = struct {
+        reduction : []const u8,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(predictions, targets) -> mean((predictions - targets)^2); 0 for n = 0
+    fn forward(predictions: []const f32, targets: []const f32) -> f32 {
+        if (predictions.len == 0) {
+            return 0.0;
+        }
+        var sum_loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            const diff = predictions[i] - targets[i];
+            sum_loss = sum_loss + diff * diff;
+            i = i + 1;
+        }
+        return sum_loss / (predictions.len as f32);
+    }
+
+    // backward: grad_input[i] = 2 (predictions[i] - targets[i]) / n
+    fn backward(predictions: []const f32, targets: []const f32, grad_input: []f32) -> void {
+        if (predictions.len == 0) {
+            return;
+        }
+        const scale = 2.0 / (predictions.len as f32);
+        var i : usize = 0;
+        while (i < predictions.len) {
+            grad_input[i] = scale * (predictions[i] - targets[i]);
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    fn mse_at(p0: f32, p1: f32, p2: f32) -> f32 {
+        const predictions : [3]f32 = [p0, p1, p2];
+        const targets : [3]f32 = [1.0, 2.0, 3.0];
+        return forward(&predictions, &targets);
+    }
+
+    fn mse_grad_at(p0: f32, p1: f32, p2: f32, index: usize) -> f32 {
+        const predictions : [3]f32 = [p0, p1, p2];
+        const targets : [3]f32 = [1.0, 2.0, 3.0];
+        var grads : [3]f32 = [0.0] ** 3;
+        backward(&predictions, &targets, &grads);
+        return grads[index];
+    }
+
+    fn mse_empty() -> f32 {
+        const none : [0]f32 = [];
+        return forward(&none, &none);
+    }
+
+    test forward_zero_on_exact_match
+        given result = mse_at(1.0, 2.0, 3.0)
+        when also = mse_empty()
+        then result == 0.0 and also == 0.0
+
+    // errors (0.5, -1, 2): (0.25 + 1 + 4) / 3 = 1.75
+    test forward_basic_case
+        given result = mse_at(1.5, 1.0, 5.0)
+        when flipped = mse_at(0.5, 3.0, 1.0)
+        then @abs(result - 1.75) < 0.000001 and @abs(flipped - result) < 0.000001
+
+    test backward_matches_finite_difference
+        given slope = (mse_at(1.5, 1.001, 5.0) - mse_at(1.5, 0.999, 5.0)) / 0.002
+        when result = mse_grad_at(1.5, 1.0, 5.0, 1)
+        then @abs(result - slope) < 0.001 and @abs(result - (-2.0 / 3.0)) < 0.000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant mse_zero_at_target
+        assert mse_at(1.0, 2.0, 3.0) == 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/neural-networks.t27 b/apps/website/public/learn/neural-networks.t27 new file mode 100644 index 0000000000..7d365b8726 --- /dev/null +++ b/apps/website/public/learn/neural-networks.t27 @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/course/neural-networks.t27 -- the t27 course on neural networks, from one neuron to a transformer block +; Source of truth for apps/website/scripts/course-from-spec.mjs (gHashTag/trinity), which reads +; it the way it reads specs/course/course.t27: the constant schema, every test block below, every +; widget in specs/widgets/gallery.t27, every lesson spec compiled clean, the Russian bundle named +; by specs/course/neural-networks-ru.t27. It writes this course into src/lib/course.generated.ts +; (the page at #/neural-networks) and a byte-identical copy of this file at +; public/learn/neural-networks.t27. ASCII only (L3), English only (LANG-EN). + +; WHAT THE COURSE IS: course 10 of specs/course/courses.t27, 27 lessons in 9 modules of 3: one +; neuron, new bends, a layer, pictures, the error, downhill, learning, memory and attention, and +; the transformer and the reward. Every lesson opens one interactive widget and one spec. The +; agents of this project think with neural networks; this course opens their parts as the +; gHashTag/t27 specs/ml specs they are written in, each with numeric tests. Every widget runs the +; fn bodies of one of those specs compiled to WebAssembly (public/widgets//logic.js, held to +; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059. + +; WHAT THE COURSE DOES NOT DO: it says no number of its own. Every number in a lesson is one the +; lesson spec computes and its widget shows. Lesson 10 is average pooling, not a convolution: the +; sliding conv2d spec (gHashTag/t27#10612) was not merged when the course was made, and the +; lesson says so. Lesson 20 shows the four inputs of XOR, not a decision region over the plane. + +; WHY 27: 3 cubed lessons, the size of a TRI-27 word. Changing the shape changes the tests. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module neural_networks; + +pub const KIND : str = "course"; +pub const ID : str = "neural-networks"; +pub const SCHEMA_VERSION : u8 = 1; +; The derived files the generator rewrites (relative to apps/website). +pub const GENERATED : [2]str = ["src/lib/course.generated.ts", "public/learn/neural-networks.t27"]; +pub const ROUTE : str = "neural-networks"; +; Share pages: learn/ for course 1, learn// for the next (specs/course/courses.t27). +pub const SHARE_PATH : str = "learn/neural-networks/"; +; The paid training every course page links to (specs/course/arithmetic-and-dsp.t27). +pub const COHORT_ROUTE : str = "fpga-training"; +pub const GALLERY : str = "specs/widgets/gallery.t27"; +pub const LOCALES : [2]str = ["en", "ru"]; +pub const RU_CONTRACT : str = "specs/course/neural-networks-ru.t27"; +; Lesson marks the reader sets are kept in this browser only, under this key, one key for +; every course. +pub const PROGRESS_KEY : str = "t27-course-done"; +pub const SENDS_NOTHING : bool = true; +; A lesson's widget is the page's main stage, so it is drawn taller than a +; gallery card (specs/widgets/gallery.t27 EMBED_* heights are for embeds in posts). +pub const TOOL_FRAME_HEIGHT : u16 = 760; +pub const PLAYER_FRAME_HEIGHT : u16 = 480; + +; --- Words on the page --------------------------------------------------------------------- +pub const TITLE : str = "Neural networks in t27: from one neuron to a transformer block"; +pub const DESCRIPTION : str = "Course 10, 27 lessons, a live widget and a t27 spec each: activations, softmax and embeddings, pooling and batch norm, losses, SGD, RMSProp and Adam, backpropagation and XOR, recurrent cells, attention, a transformer block and PPO. Every number is computed by a compiled spec."; +pub const SAY_KICKER : str = "Course"; +pub const SAY_LEAD : str = "The agents of this project think with neural networks, and here their parts are written as t27 specs with tests, specs the compiler checks. Every widget runs the fn bodies of a specs/ml spec compiled to WebAssembly: move a slider and the spec answers."; +pub const SAY_SHAPE : str = "9 modules of 3 lessons, 27 cells. A filled cell is a lesson you marked done."; +pub const SAY_START : str = "Start lesson 1"; +pub const SAY_CONTINUE : str = "Continue"; +pub const SAY_MODULE : str = "Module {0}"; +pub const SAY_LESSON : str = "Lesson {0} of {1}"; +pub const SAY_GOAL : str = "You will learn"; +pub const SAY_TRY : str = "Try it"; +pub const SAY_ALSO : str = "Also try"; +pub const SAY_ALSO_HINT : str = "Each one swaps the widget above."; +pub const SAY_BACK_TO_MAIN : str = "Back to this lesson's widget"; +pub const SAY_SPEC : str = "Open the lesson's spec in the player"; +pub const SAY_OPEN_PAGE : str = "Open the widget on its own page"; +pub const SAY_WIDGET_LANG : str = "Widgets keep their own English words: each one lives in its own t27 spec."; +pub const SAY_PREV : str = "Previous"; +pub const SAY_NEXT : str = "Next"; +pub const SAY_ALL : str = "All lessons"; +pub const SAY_MARK : str = "Mark as done"; +pub const SAY_MARKED : str = "Done"; +pub const SAY_PROGRESS : str = "{0} of {1} done"; +pub const SAY_PRIVATE : str = "Progress stays in this browser; nothing is sent."; +pub const SAY_SOURCE : str = "This course is itself a t27 spec: read it"; +pub const SAY_COHORT : str = "Looking for the paid FPGA training? It moved to its own page."; +pub const SAY_NOT_FOUND : str = "No lesson has this address."; +pub const SAY_OPEN_LESSON : str = "Open the interactive lesson"; +pub const SAY_OPEN_COURSE : str = "Open the interactive course"; +pub const SAY_SEO_TITLE : str = "{0}: neural networks course, lesson {1} of {2}"; +pub const SAY_SHARE : str = "Link to share, with a preview card"; +pub const SAY_NEXT_COURSE : str = "Next course"; +pub const SAY_PREV_COURSE : str = "Previous course"; + +; --- Modules ------------------------------------------------------------------------------- +pub const LESSONS_PER_MODULE : u8 = 3; +pub const MODULE_COUNT : u8 = 9; +pub const MODULE_IDS : [9]str = ["one-neuron", "new-bends", "a-layer", "pictures", "the-error", "downhill", "learning", "memory-and-attention", "transformer-and-reward"]; +pub const MODULE_TITLES : [9]str = [ + "One neuron", + "New bends", + "A layer", + "Pictures", + "The error", + "Downhill", + "Learning", + "Memory and attention", + "The transformer and the reward" +]; +pub const MODULE_LINES : [9]str = [ + "A neuron sums its inputs and bends the sum: ReLU, the sigmoid and tanh, and where each one stops passing a gradient back.", + "The smooth curves of current models: GELU with its dip, Swish with its knob, and ELU with a floor instead of a cliff.", + "What sits around the neurons: softmax turns scores into a choice, an embedding turns a word into numbers, dropout switches units off.", + "Reading a picture in patches: a window averaged over its patch, max pooling, and batch normalisation of features on different scales.", + "How wrong a guess is, as one number: mean squared error, cross-entropy for probabilities, and the Huber loss for outliers.", + "Walking down the loss: gradient descent with momentum, RMSProp that ignores the gradient's size, and Adam that combines them.", + "Where the gradients come from and what they achieve: backpropagation through a layer, a network that learns XOR, and LAMB for large batches.", + "Networks that read a sequence: a recurrent cell and its fading echo, the gates of an LSTM, and attention over every position at once.", + "The parts of a transformer and of an agent: positions as clocks, one encoder block, and PPO, which learns from reward without lurching." +]; + +; --- Lessons ------------------------------------------------------------------------------- +; LESSON_WIDGETS names the widget the lesson opens; every one is a gallery id, and no two +; lessons of any course open the same one. Each module's three widgets are offered in each +; other's LESSON_ALSO, next to related widgets of this course and of the ternary course. +; LESSON_SPECS is the spec under public/t27/files/ the lesson opens in the player, and the spec +; whose compiled fn bodies the widget runs. +pub const LESSON_COUNT : u8 = 27; +pub const LESSON_IDS : [27]str = [ + "relu", "the-sigmoid", "tanh-and-saturation", + "gelu", "swish-and-silu", "elu", + "softmax-and-temperature", "embeddings", "dropout", + "patches-of-a-picture", "max-pooling", "batch-normalisation", + "mean-squared-error", "cross-entropy", "the-huber-loss", + "gradient-descent", "rmsprop", "adam", + "backpropagation", "learning-xor", "lamb-and-large-batches", + "a-recurrent-cell", "lstm-gates", "attention", + "positional-encoding", "an-encoder-block", "ppo-and-the-reward" +]; +pub const LESSON_MODULES : [27]str = [ + "one-neuron", "one-neuron", "one-neuron", + "new-bends", "new-bends", "new-bends", + "a-layer", "a-layer", "a-layer", + "pictures", "pictures", "pictures", + "the-error", "the-error", "the-error", + "downhill", "downhill", "downhill", + "learning", "learning", "learning", + "memory-and-attention", "memory-and-attention", "memory-and-attention", + "transformer-and-reward", "transformer-and-reward", "transformer-and-reward" +]; +pub const LESSON_WIDGETS : [27]str = [ + "nn-relu", "nn-sigmoid", "nn-tanh", + "nn-gelu", "nn-silu", "nn-elu", + "nn-softmax", "nn-embedding", "nn-dropout", + "nn-conv", "nn-maxpool", "nn-batchnorm", + "nn-mse", "nn-bce", "nn-huber", + "nn-sgd", "nn-rmsprop", "nn-adam", + "nn-backprop", "nn-xor", "nn-lamb", + "nn-rnn", "nn-lstm", "nn-attention", + "nn-positions", "nn-encoder", "nn-ppo" +]; +pub const LESSON_ALSO : [27]str = [ + "nn-sigmoid,nn-tanh,tc-one-neuron", + "nn-relu,nn-tanh,nn-bce", + "nn-relu,nn-sigmoid", + "nn-silu,nn-elu,nn-encoder", + "nn-gelu,nn-elu,nn-relu", + "nn-relu,nn-silu,nn-gelu", + "nn-embedding,nn-dropout,nn-bce", + "nn-softmax,nn-dropout,nn-positions", + "nn-softmax,nn-embedding", + "nn-maxpool,nn-batchnorm,tc-detector", + "nn-conv,nn-batchnorm", + "nn-conv,nn-maxpool,nn-encoder", + "nn-bce,nn-huber", + "nn-mse,nn-huber,nn-sigmoid", + "nn-mse,nn-bce", + "nn-rmsprop,nn-adam,nn-mse", + "nn-sgd,nn-adam", + "nn-sgd,nn-rmsprop,nn-lamb", + "nn-xor,nn-lamb,tc-tiny-layer", + "nn-backprop,nn-lamb,tc-tiny-layer", + "nn-adam,nn-xor,nn-backprop", + "nn-lstm,nn-attention", + "nn-rnn,nn-attention,nn-sigmoid", + "nn-rnn,nn-lstm,nn-encoder", + "nn-attention,nn-encoder,nn-embedding", + "nn-attention,nn-positions,nn-batchnorm", + "nn-softmax,nn-adam,nn-encoder" +]; +pub const LESSON_SPECS : [27]str = [ + "specs/ml/activation/relu_activation.t27", + "specs/ml/activation/sigmoid_activation.t27", + "specs/ml/activation/tanh_activation.t27", + "specs/ml/activation/gelu_activation.t27", + "specs/ml/activation/silu_swish_activation.t27", + "specs/ml/activation/elu_activation.t27", + "specs/ml/activation/softmax.t27", + "specs/ml/layers/embedding_layer.t27", + "specs/ml/layers/dropout_layer.t27", + "specs/ml/layers/avgpool2d_layer.t27", + "specs/ml/layers/maxpool2d_layer.t27", + "specs/ml/layers/batchnorm_layer.t27", + "specs/ml/loss/mse_loss.t27", + "specs/ml/loss/binary_crossentropy_loss.t27", + "specs/ml/loss/huber_loss.t27", + "specs/ml/optimizer/sgd.t27", + "specs/ml/optimizer/rmsprop.t27", + "specs/ml/optimizer/adam.t27", + "specs/ml/layers/dense_layer.t27", + "specs/ml/pathway/mlp.t27", + "specs/ml/optimizer/lamb.t27", + "specs/ml/recurrent/rnn_cell.t27", + "specs/ml/recurrent/lstm_single.t27", + "specs/ml/recurrent/attention_mechanism.t27", + "specs/ml/transformer/positional_encoding.t27", + "specs/ml/transformer/encoder_block.t27", + "specs/ml/rl/ppo_clip_loss.t27" +]; +pub const LESSON_TITLES : [27]str = [ + "ReLU: keep the positive part", + "The sigmoid: a number into a probability", + "tanh and saturation", + "GELU: a dip below zero", + "Swish and SiLU", + "ELU: a floor, not a cliff", + "Softmax and temperature", + "Embeddings", + "Dropout", + "Patches of a picture", + "Max pooling", + "Batch normalisation", + "Mean squared error", + "Cross-entropy", + "The Huber loss", + "Gradient descent", + "RMSProp", + "Adam", + "Backpropagation", + "Learning XOR", + "LAMB and large batches", + "A recurrent cell", + "LSTM gates", + "Attention", + "Positional encoding", + "An encoder block", + "PPO and the reward" +]; +pub const LESSON_GOALS : [27]str = [ + "What ReLU does to a positive and to a negative input, and why a slope of 0 stops a unit from learning.", + "How the sigmoid maps any input to a probability, and why its slope limits deep networks.", + "Why tanh is centred on zero, and where its slope falls so low that a unit stops learning.", + "What GELU computes, why it dips below zero, and how close its tanh shortcut comes.", + "How x times sigmoid(beta x) gates itself, and how one parameter moves it from a smooth curve to ReLU.", + "How ELU keeps a soft negative side with a floor at -alpha, and why its slope never quite dies.", + "How softmax turns scores into probabilities that sum to one, and what the temperature does to them.", + "How a token becomes a row of numbers, and why learning changes only the rows that were read.", + "Why switching units off while training helps, and why the survivors must be scaled.", + "Why networks read a picture in patches, and what a 2 x 2 window averaged over each patch gives.", + "What max pooling keeps, where it remembers taking it from, and where the gradient goes.", + "How batch norm puts features on different scales on one scale, and what it uses at inference.", + "How MSE turns every miss into one number, why it chases large errors, and where its gradient points.", + "Why cross-entropy charges a confident wrong answer so much, and why that is what trains a classifier.", + "How the Huber loss treats a small error like squared error and a large one linearly, so outliers pull less.", + "How gradient descent walks down a loss, what momentum adds, and why too large a rate never settles.", + "How RMSProp divides each step by a running root mean square, so the step no longer depends on the gradient's size.", + "How Adam combines momentum with a running scale, and why its bias correction makes step 1 a fixed size.", + "How the gradient of each weight and each input of a layer follows from the gradient of its outputs.", + "Why one neuron cannot learn XOR, and how a hidden layer trained by backpropagation does.", + "How LAMB scales each layer's step by its own weight norm, so one learning rate suits layers of every size.", + "How a recurrent cell carries a state from step to step, and why that memory fades.", + "How the forget, input and output gates of an LSTM decide what the cell keeps, writes and shows.", + "How attention scores every query against every key, what a softmax over each row gives, and what the causal mask removes.", + "How sines and cosines at falling frequencies give every position its own vector, and why a shift is a turn.", + "What one transformer encoder block does to its input, and what moving the norms in front changes.", + "How PPO turns a reward into a policy update, and how its clip keeps one update from going too far." +]; +pub const LESSON_TEXTS : [27]str = [ + "A neuron adds up its weighted inputs and passes the sum through an activation. ReLU is the plainest one, max(0, x): a positive sum goes through unchanged and a negative one becomes 0. Its slope is 1 or 0, and a slope of 0 is a unit that has stopped learning, because no gradient flows back through it. A leaky slope fixes that: with a slope of 0.1, x = -2 gives -0.2 and passes back a gradient of 0.1. The spec relu_activation.t27 computes both curves the widget draws.", + "The sigmoid 1 / (1 + e^-x) squeezes the whole number line into 0 to 1, which is why it reads as a probability: 2 becomes 0.8808 and -4 becomes 0.018. Its slope is s (1 - s), computed from the output s itself, and it is largest at 0, where it is 0.25; at x = 8 it is 0.000335. A gradient that passes back through a stack of sigmoids is multiplied by at most 0.25 at each one, which is why deep sigmoid networks trained slowly. The spec sigmoid_activation.t27 computes the curve and the slope.", + "tanh is a sigmoid stretched to -1..1 and centred on 0, so a layer of tanh units passes on values that average near zero, and its slope reaches 1 at the centre. It still saturates: at 2.5 the output is 0.9866 and the slope only 0.0266. The red band marks every input where the slope is under 0.1, beyond about 1.8 on either side, and a unit whose inputs live there barely learns. The spec tanh_activation.t27 computes the curve, the slope and its own batch, tanh of 0, 1 and 2: 0, 0.762 and 0.964.", + "GELU weighs x by the chance that a standard normal draw is below it: GELU(x) = x Phi(x). A large positive input passes, a large negative one vanishes, and in between the curve dips to about -0.17 near x = -0.75 before it rises. BERT and GPT use it in their feed-forward layers. The exact form needs erf, which the spec computes with the Abramowitz-Stegun fit, good to 1.5e-7, and it also computes the tanh shortcut: at -0.75 they give -0.16997 and -0.17004. The spec gelu_activation.t27 computes both curves and their slopes.", + "Swish is x times sigmoid(beta x), a unit that gates itself. At beta 1 it is called SiLU, and its lowest point is -0.2785 near x = -1.28. Raise beta and the gate sharpens: at beta 8 the curve is ReLU with rounded corners; at beta 0.5 it is a gentle slope through zero. One parameter moves the unit between a smooth curve and a switch, and a network can learn it. The spec silu_swish_activation.t27 computes the curve and its slope for any beta, and its own batch at -2, 0 and 2: -0.238, 0 and 1.762.", + "ELU keeps the positive side of ReLU and replaces the cliff on the negative side with alpha (e^x - 1), a curve that flattens toward -alpha. With alpha 1, x = -3 gives -0.9502, already near the floor of -1, and the slope there is 0.0498: small, but not 0, so the unit can still move. Because the negative outputs are not thrown away, a layer's outputs average closer to 0. The spec elu_activation.t27 computes the curve, the slope and the floor, and its own batch at -1, 0 and 2: -0.632, 0 and 2.", + "A classifier ends with one score per class, and softmax turns the scores into probabilities: exp of each score over the sum of all of them. Scores 1, 2 and 3 become 0.090, 0.245 and 0.665. Dividing the scores by a temperature first changes how sure it is: at 0.5 the top score takes 0.867, at 5 the three are 0.27, 0.33 and 0.40. A language model picks its next token from exactly this, and the temperature setting of a chat model is this T. The spec softmax.t27 subtracts the largest score first, so exp never overflows.", + "A network cannot multiply a word, so each token is an index into a table with one row of numbers per token, and looking a token up copies its row. In the spec the table has 4 tokens of width 2 and row v holds (10 v, 10 v + 1), so token 2 reads (20, 21). Learning sends the gradient back only to the rows that were read, and a token read twice collects both: gradient rows (1, 2) and (3, 4) on token 2 add up to (4, 6). The spec embedding_layer.t27 computes the lookup and the gradient.", + "While training, dropout switches off a share p of the units at random, so the rest cannot lean on any one of them. The units that survive must then be scaled, or the next layer would see the signal at another size in training than at inference. Inverted dropout scales them by 1 / (1 - p) while training: with p = 0.5, input 1, 2, 3, 4 becomes 2, 0, 6, 0, and inference is a plain pass. Classic dropout keeps 1, 0, 3, 0 and scales by 0.5 at inference instead. The spec dropout_layer.t27 uses a fixed mask, keep, drop, keep, drop, so the numbers are the same every time.", + "A picture is a grid of numbers, and networks read it in small patches so that the same detector works anywhere in it. Here a 2 x 2 window steps by 2 over a 4 x 4 image whose cell i holds i, and each output is the average of its patch: 2.5, 4.5, 10.5 and 12.5. In the backward pass each output's gradient is split equally over its 4 cells. This is average pooling: a convolution would weight the 4 cells with a learned kernel, and its spec, t27#10612, is not merged yet. The spec avgpool2d_layer.t27 computes both passes.", + "Max pooling keeps the largest value of each window and drops the rest, so the network cares less about exactly where a feature sits. On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2, taken from cells 5, 6, 13 and 11. Overlapping 3 x 3 windows with stride 1 keep 8, 8, 9 and 9. In the backward pass each window's whole gradient goes to its maximum: gradients 1, 2, 3 and 4 land on cells 5, 6, 13 and 11, and every other cell gets 0. The spec maxpool2d_layer.t27 computes the outputs, their positions and the gradient.", + "Features on different scales pull a network around: in the spec's batch one feature is ten times another. Batch normalisation subtracts each feature's batch mean and divides by its spread, so the features 1, 2, 3, 4 and 10, 20, 30, 40 both come out as -1.34, -0.45, 0.45 and 1.34, and -1, -1, 1, 1 comes out as -1 and 1. A learned gamma and beta then scale and shift it back where that helps. At inference the layer uses running averages instead of the batch: with mean 0, variance 1, gamma 1 and beta 0.25, the inputs 1, 2 and 3 give 1.25, 2.25 and 3.25. The spec batchnorm_layer.t27 computes both.", + "A loss turns all the misses of a model into one number to push down. Mean squared error averages the squared misses: predictions 1.5, 2 and 2 against targets 1, 2 and 3 cost (0.25 + 0 + 1) / 3 = 0.4167. Squaring makes a miss of 2 cost 4 times a miss of 1, so MSE chases large errors. Its gradient for each prediction is 2 (p - t) / n, here 0.333, 0 and -0.667: each prediction is pushed back toward its target. As a function of one prediction the loss is a parabola, a bowl with one bottom. The spec mse_loss.t27 computes the loss and the gradient.", + "A classifier outputs a probability, and cross-entropy charges -log of the probability it gave to the true answer. Predictions 0.8, 0.3 and 0.9 against answers 1, 0 and 1 cost 0.2284 on average. Being sure and right is nearly free: 0.99, 0.01 and 0.99 cost 0.0101. Being sure and wrong is expensive: 0.01, 0.99 and 0.01 cost 4.6052, and toward 0 the cost grows without bound, which is why the spec clips p to [1e-7, 1 - 1e-7]. Its gradient is largest exactly where the model is sure and wrong. The spec binary_crossentropy_loss.t27 computes the loss and the gradient, from probabilities or from logits.", + "Squared error lets one outlier dominate: an error of 3 costs 4.5 as half its square, as much as 36 errors of 0.5. Huber is half the square while |e| is within delta and then grows only linearly, delta |e| - delta^2 / 2, so with delta 1 that error costs 2.5. The two pieces meet with the same value and slope, and the gradient never grows past delta: a far-off point pulls on the model with a bounded force. For the spec's pair of errors 0.5 and 3 the mean is 1.3125, against 2.3125 for half the square. The spec huber_loss.t27 computes both.", + "Training is walking downhill on the loss. Gradient descent moves a weight by -lr times its gradient each step; in the spec the loss is (x - 3)^2 from x = 0, and lr 0.1 reaches 2.99996 in 50 steps. Momentum adds a share of the last move, which speeds up a long slope and overshoots a sharp bottom: at 0.9 the weight shoots past 3 to about 5.13 and rings down to 3.09 after 50 steps. Nesterov takes the gradient one step ahead and swings less, to about 4.25. Too large a rate never settles: at lr 1 the weight bounces between 0 and 6 for good. The spec sgd.t27 computes every step.", + "The right step size depends on the size of the gradient, and different weights see gradients a million times apart. RMSProp keeps a running mean of the squared gradient, the cache, and divides each step by its root, so the step has no units: with a constant gradient of 0.001, 0.5 or 1000 the weight moves by exactly the same 0.0316 on step 1 and walks the same path, reaching -0.0914 after 100 steps at lr 0.01. The decay sets how slowly the cache fills: at 0.99 the same 100 steps end at -1.0261. The spec rmsprop.t27 computes the weight and the cache.", + "Adam combines the two ideas: m, a running mean of the gradient, as in momentum, and v, a running mean of its square, as in RMSProp; the step is lr m / sqrt(v). Both start at 0 and are too small early on, so Adam divides them by 1 - beta^t, and on step 1 that makes the move exactly lr times the sign of the gradient: gradients 2, -40 and 0.5 all move their weights by 0.001. On the spec's bowl (x - 3)^2 at lr 0.1, Adam rises from 0, overshoots to about 3.18 and settles at 3.00005 by step 200. The spec adam.t27 computes every step.", + "To learn, every weight needs to know how the loss changes when it moves. Backpropagation answers one layer at a time: given g, how much the loss wants each output to move, the weight from input i to output o gets g_o x_i, and input i gets the sum over o of W[o][i] g_o, which it hands on to the layer below. With inputs (1, 2, 3) and g = (1, 0.5) the weight gradients are 1, 2, 3 and 0.5, 1, 1.5, and the input gradients 0.5, 2 and 3.5. The layer is linear, so moving x0 by 1 moves the loss g . y from 15.25 to 15.75, by its gradient 0.5. The spec dense_layer.t27 computes all three.", + "XOR is 1 when exactly one of two inputs is 1. No straight line separates the cases that give 1 from those that give 0, so a single neuron cannot learn it. A hidden layer bends the space: the spec trains a 2-8-1 network of ReLUs by backpropagation, lr 0.05, from fixed initial weights. Its loss falls from 0.8896 in epoch 1 to 1.8e-13 after 2000 epochs, and its four answers come out within 4e-7 of 0, 1, 1 and 0. The widget runs that training in your browser, from scratch for every point of the curve. The spec mlp.t27 holds the network and the test that it learns.", + "Training with very large batches needs a large learning rate, and one rate can be too large for a small layer and too small for a big one. LAMB takes an Adam-style update for each layer and rescales it by the trust ratio, the layer's weight norm, capped at 10, over the update's norm, so every layer moves by the same fraction of itself. In the spec, the weights (1, 2) times a scale take a step whose norm is 0.001 times theirs: 0.00447 at scale 2, and once the weight norm passes 10, near scale 4.47, the step stays at 0.01. The spec lamb.t27 computes the update for one layer and for two at once.", + "A sentence comes one word at a time, and a recurrent cell carries a state h from one step to the next: h' = tanh(W_x x + W_h h + b). In the spec's tiny cell W_x is 1 and W_h 0.5, so a single pulse gives 0.7616, 0.3634 and 0.1797: the memory of it roughly halves each step. A second pulse at step 3 lifts h to 0.7968, a little above where the single pulse began, because the old memory is still there. After 8 steps only 0.0466 is left. That fading is why plain cells forget long contexts. The spec rnn_cell.t27 computes each step.", + "An LSTM cell keeps a separate memory c and three gates, each a sigmoid between 0 and 1: forget scales the old memory, input lets in new content g, and output decides how much of the memory to show. c' = f c + i g and h' = o tanh(c'). In the spec's fixture every weight is 0, so each gate is the sigmoid of its bias: with the forget gate at 0.9975 and the input gate at 0.0025, a memory of 1 comes out as 0.9975, and the output is 0.7587. Because c passes through with only a multiply by f, its gradient survives many steps too. The spec lstm_single.t27 computes the cell.", + "Attention lets each position decide which other positions to read. Every query is scored against every key, q . k / sqrt(d), and a softmax turns each row of scores into weights that sum to 1; the output is the values averaged by those weights. Two heads do it on the two halves of the vector. With a causal mask a position cannot read the future: in head 0, position 0 reads only itself, position 1 splits 0.452 and 0.548, and position 2 spreads 0.230, 0.321 and 0.449. Without the mask every row spreads over all three keys, from 0.21 to 0.47. The spec attention_mechanism.t27 computes every weight on its own fixture.", + "Attention treats its input as a set, so the order of the words has to be added to them. The sinusoidal encoding gives each position d numbers: the sin and cos of the position times a frequency that falls by 10000^(2/d) from pair to pair. With d = 8 the four pairs turn by 1, 0.1, 0.01 and 0.001 radians per position, like the hands of four clocks: position 5 reads -0.959, 0.284 in its fast pair and 0.005, 1.000 in its slow one. Each pair has length 1, and a shift by k positions turns every pair by its own fixed angle. The spec positional_encoding.t27 computes every value.", + "A transformer layer is two sublayers, each wrapped in a residual add and a layer norm: self-attention mixes the positions, then a feed-forward net of width 8 works on each position alone. In the post-norm order of the original paper the block ends with a norm, so every output row has mean 0 and variance 1.000. Pre-norm puts the norms in front of each sublayer and ends on a residual add, so its rows come out at variances 2.73, 3.33 and 0.96; deep stacks train more easily that way, with one norm added at the very top. The spec encoder_block.t27 runs one block on 3 positions, d_model 4 and 2 heads.", + "An agent learns from reward by making good actions more likely. PPO measures a change of policy by the ratio r of the new probability of an action to the old one and multiplies it by the advantage A, how much better the action did than expected. Then it clips: once r has moved more than eps the way A rewards, the objective goes flat. At r = 1.5, A = 1 and eps 0.2 the raw r A is 1.5, but PPO counts 1.2, so one batch cannot push the policy far. On the spec's batch, ratios 1, 1.1 and 0.9 with advantages 2, 1.5 and 3, the policy loss is -2.1167. The spec ppo_clip_loss.t27 computes it." +]; +pub const LESSON_TASKS : [27]str = [ + "Put x at -2 and read the slope with and without the leak; then find the slope at x = 1.5.", + "Find the input where the probability is 0.5; then drag to 6 and read how little slope is left.", + "Drag x until the band starts and read the slope there; then compare the slope at 0 and at 2.5.", + "Find the lowest point of the curve by its slope; then compare the exact and the tanh form at -3.", + "Hold x at -1.28 and raise beta from 1 to 8; then find the beta at which the dip is gone at this scale.", + "Set alpha to 0.5 and read the floor; then find how far left x must go before the slope is under 0.01.", + "Cool the temperature to 0.1 and read the three probabilities; then make a tie and heat it.", + "Read token 2 twice and then tokens 1 and 3; count the rows whose gradient is not 0 each time.", + "Compare the outputs of the four modes; then read the gradient of a dropped unit in training.", + "Tap each patch and check its average by eye; then switch to the gradient and read what each cell of window 4 receives.", + "Switch to 3 x 3 windows and find the cell two outputs share; then turn on the gradient for 2 x 2 windows.", + "Compare the two normalised columns; then set the running mean 2 and variance 4 and read the inference outputs.", + "Move prediction 2 onto its target and read the loss; then drag along the bowl and find its bottom.", + "Drag prediction 0 toward 0.01 and watch the curve; then read the gradient bars at 0.5, 0.5 and 0.5.", + "Set delta to 0.5 and drag the error to 3; then find where the two curves part.", + "Find the largest learning rate that still settles without momentum; then add momentum 0.9 and count the swings.", + "Switch between the three gradients and check that the lines do not move; then raise the decay to 0.99.", + "Give the three gradients very different sizes and read the weights after step 1; then find where the path tops out.", + "Set g = (1, 0) and read which edges go dark; then set g = (-2, 1) and check the input gradients by hand.", + "Drag the epochs back to 100 and read the four answers; then find the epoch where the curve stops falling.", + "Read the step at scales 1 and 2 and compare; then drag past the bend and explain why the line goes flat.", + "Load one pulse and read how many steps it takes to fall under 0.1; then make the input alternate.", + "Load Remember and then Forget and compare the new memory; then write with the input gate open.", + "Turn the mask off and on and read row 0; then compare the two heads on row 2.", + "Step from position 0 to 1 and watch which clock moves; then jump to 37 and find the pair that still points up.", + "Switch between post-norm and pre-norm and read the row variances; then find the position head 1 reads most.", + "Make the advantage negative and find where the curve goes flat now; then widen eps to 0.5." +]; + +; --- Claims -------------------------------------------------------------------------------- +test the_course_is_three_cubed { + assert LESSONS_PER_MODULE == 3; + assert MODULE_COUNT == 9; + assert LESSON_COUNT == 27; + assert MODULE_COUNT * LESSONS_PER_MODULE == LESSON_COUNT; + assert LESSON_COUNT == 3 * 3 * 3; +} + +test it_starts_at_one_neuron_and_ends_with_a_reward { + assert MODULE_IDS[0] == "one-neuron"; + assert LESSON_WIDGETS[0] == "nn-relu"; + assert LESSON_SPECS[0] == "specs/ml/activation/relu_activation.t27"; + assert MODULE_IDS[8] == "transformer-and-reward"; + assert LESSON_WIDGETS[26] == "nn-ppo"; + assert LESSON_SPECS[26] == "specs/ml/rl/ppo_clip_loss.t27"; +} + +test activations_come_before_layers { + assert MODULE_IDS[1] == "new-bends"; + assert LESSON_WIDGETS[3] == "nn-gelu"; + assert MODULE_IDS[2] == "a-layer"; + assert LESSON_SPECS[6] == "specs/ml/activation/softmax.t27"; +} + +test the_picture_lesson_is_pooling_until_conv2d_slides { + assert MODULE_IDS[3] == "pictures"; + assert LESSON_WIDGETS[9] == "nn-conv"; + assert LESSON_SPECS[9] == "specs/ml/layers/avgpool2d_layer.t27"; + assert LESSON_WIDGETS[10] == "nn-maxpool"; +} + +test losses_then_optimizers_then_learning { + assert MODULE_IDS[4] == "the-error"; + assert MODULE_IDS[5] == "downhill"; + assert LESSON_WIDGETS[17] == "nn-adam"; + assert MODULE_IDS[6] == "learning"; + assert LESSON_WIDGETS[19] == "nn-xor"; + assert LESSON_SPECS[19] == "specs/ml/pathway/mlp.t27"; +} + +test memory_then_attention_then_the_transformer { + assert MODULE_IDS[7] == "memory-and-attention"; + assert LESSON_WIDGETS[23] == "nn-attention"; + assert LESSON_WIDGETS[25] == "nn-encoder"; + assert LESSON_SPECS[25] == "specs/ml/transformer/encoder_block.t27"; +} + +test the_course_sends_nothing { + assert SENDS_NOTHING == true; + assert LOCALES[0] == "en"; + assert LOCALES[1] == "ru"; +} diff --git a/apps/website/public/learn/neural-networks/card.png b/apps/website/public/learn/neural-networks/card.png new file mode 100644 index 0000000000000000000000000000000000000000..e02c1f1f95eb0d2c8599f43c19a02f7f4d2ba9a6 GIT binary patch literal 56300 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≻r6 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 + + + + + +Neural networks in t27: from one neuron to a transformer block · t27 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+

Course

+

Neural networks in t27: from one neuron to a transformer block

+

The agents of this project think with neural networks, and here their parts are written as t27 specs with tests, specs the compiler checks. Every widget runs the fn bodies of a specs/ml spec compiled to WebAssembly: move a slider and the spec answers.

+

Course 10, 27 lessons, a live widget and a t27 spec each: activations, softmax and embeddings, pooling and batch norm, losses, SGD, RMSProp and Adam, backpropagation and XOR, recurrent cells, attention, a transformer block and PPO. Every number is computed by a compiled spec.

+

Open the interactive course →

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/patches-of-a-picture/card.png b/apps/website/public/learn/patches-of-a-picture/card.png new file mode 100644 index 0000000000000000000000000000000000000000..7f8b104c3a5109f112ca75fe07c72005704873a2 GIT binary patch literal 52818 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

Vfb}LKC+p5amZhHfzCXppF^RVc*m& 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 + + + + + +Patches of a picture: neural networks course, lesson 10 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

Patches of a picture

+

You will learn

Why networks read a picture in patches, and what a 2 x 2 window averaged over each patch gives.

+

A picture is a grid of numbers, and networks read it in small patches so that the same detector works anywhere in it. Here a 2 x 2 window steps by 2 over a 4 x 4 image whose cell i holds i, and each output is the average of its patch: 2.5, 4.5, 10.5 and 12.5. In the backward pass each output's gradient is split equally over its 4 cells. This is average pooling: a convolution would weight the 4 cells with a learned kernel, and its spec, t27#10612, is not merged yet. The spec avgpool2d_layer.t27 computes both passes.

+

Try it

Tap each patch and check its average by eye; then switch to the gradient and read what each cell of window 4 receives.

+

Open the interactive lesson →

+
Patches of a picture: a 2 x 2 window, averaged
Patches of a picture: a 2 x 2 window, averaged ↗
+

Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch.

+

specs/ml/layers/avgpool2d_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// 2D average pooling formula | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the kernel and stride were string constants typed `[]u32`, forward only
+// asserted that its input was non-empty, and the tests asserted `true` or
+// `result != undefined`. Average pooling now runs over one square H x H channel
+// with the default 2 x 2 window and stride 2 and no padding, and each test checks
+// numbers.
+
+module Avgpool2d;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_KERNEL : u32 = 2;
+    const DEFAULT_STRIDE : u32 = 2;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PoolConfig = struct {
+        kernel_size : []u32,
+        stride : []u32,
+        padding : []u32,
+    };
+
+    pub const PoolShape = struct {
+        batch : u32,
+        channels : u32,
+        height_in : u32,
+        width_in : u32,
+        height_out : u32,
+        width_out : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Output side for an input side n: (n - k) / stride + 1, and 0 when no window fits
+    fn calc_output_size(height_in: u32) -> u32 {
+        if (height_in < DEFAULT_KERNEL) {
+            return 0;
+        }
+        return (height_in - DEFAULT_KERNEL) / DEFAULT_STRIDE + 1;
+    }
+
+    // output[oy][ox] = mean of the k x k window at (oy * stride, ox * stride) of a side x side
+    // input; returns the number of outputs written
+    fn forward(input: []const f32, side: u32, output: []f32) -> u32 {
+        const n = calc_output_size(side);
+        const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL));
+        var oy : u32 = 0;
+        while (oy < n) {
+            var ox : u32 = 0;
+            while (ox < n) {
+                var sum : f32 = 0.0;
+                var ky : u32 = 0;
+                while (ky < DEFAULT_KERNEL) {
+                    var kx : u32 = 0;
+                    while (kx < DEFAULT_KERNEL) {
+                        sum = sum + input[(oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx];
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                output[oy * n + ox] = sum / area;
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+        return n * n;
+    }
+
+    // backward: each window's gradient is shared equally by its k * k inputs
+    fn backward(grad_output: []const f32, side: u32, grad_input: []f32) -> void {
+        const n = calc_output_size(side);
+        const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL));
+        var i : usize = 0;
+        while (i < grad_input.len) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var oy : u32 = 0;
+        while (oy < n) {
+            var ox : u32 = 0;
+            while (ox < n) {
+                var ky : u32 = 0;
+                while (ky < DEFAULT_KERNEL) {
+                    var kx : u32 = 0;
+                    while (kx < DEFAULT_KERNEL) {
+                        const idx = (oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx;
+                        grad_input[idx] = grad_input[idx] + grad_output[oy * n + ox] / area;
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+    }
+
+    // 4 x 4 input 0..15, row-major: windows average to 2.5, 4.5, 10.5, 12.5
+    fn pool4_at(index: usize) -> f32 {
+        var input : [16]f32 = [0.0] ** 16;
+        var i : usize = 0;
+        while (i < 16) {
+            input[i] = @as(f32, @floatFromInt(i));
+            i = i + 1;
+        }
+        var output : [4]f32 = [0.0] ** 4;
+        _ = forward(&input, 4, &output);
+        return output[index];
+    }
+
+    // forward over a 2 x 2 input (1, 2, 3, 4) or a 1 x 1 input (5); returns the outputs written
+    fn pool_count(side: u32) -> u32 {
+        const four : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        const one : [1]f32 = [5.0];
+        var output : [1]f32 = [-1.0];
+        if (side == 2) {
+            return forward(&four, 2, &output);
+        }
+        return forward(&one, 1, &output);
+    }
+
+    fn pool2_value() -> f32 {
+        const four : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var output : [1]f32 = [-1.0];
+        _ = forward(&four, 2, &output);
+        return output[0];
+    }
+
+    fn backward4_at(index: usize) -> f32 {
+        const grad_output : [4]f32 = [4.0, 8.0, 12.0, 16.0];
+        var grad_input : [16]f32 = [9.0] ** 16;
+        backward(&grad_output, 4, &grad_input);
+        return grad_input[index];
+    }
+
+    fn valid_input() -> u32 {
+        return calc_output_size(4);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test calc_output_size_basic_case
+        given result = calc_output_size(4)
+        then result == 2
+
+    test calc_output_size_valid_input
+        given input = 10
+        when result = calc_output_size(input)
+        then result == 5
+
+    // A 1 x 1 input holds no 2 x 2 window
+    test calc_output_size_small_input
+        given input = 1
+        when result = calc_output_size(input)
+        then result == 0 and calc_output_size(2) == 1
+
+    test calc_output_size_large_input
+        given input = 1000
+        when result = calc_output_size(input)
+        then result == 500 and calc_output_size(1001) == 500
+
+    test forward_basic_case
+        given first = pool4_at(0)
+        when last = pool4_at(3)
+        then first == 2.5 and pool4_at(1) == 4.5 and pool4_at(2) == 10.5 and last == 12.5
+
+    // A 2 x 2 input is one window: the mean of 1, 2, 3, 4
+    test forward_non_empty_input
+        given count = pool_count(2)
+        when value = pool2_value()
+        then count == 1 and value == 2.5
+
+    test forward_single_element
+        given count = pool_count(1)
+        then count == 0
+
+    // Each of a window's 4 inputs gets a quarter of its gradient
+    test backward_spreads_the_gradient
+        given corner = backward4_at(0)
+        when last = backward4_at(15)
+        then corner == 1.0 and backward4_at(5) == 1.0 and backward4_at(2) == 2.0 and last == 4.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // kernel_size[i] >= 1
+    invariant avgpool2d_constraint_0
+        assert DEFAULT_KERNEL >= 1
+
+    // stride[i] >= 1
+    invariant avgpool2d_constraint_1
+        assert DEFAULT_STRIDE >= 1
+
+    // stride[i] <= kernel_size[i]: windows tile the input without gaps
+    invariant avgpool2d_constraint_2
+        assert DEFAULT_STRIDE <= DEFAULT_KERNEL
+
+    // name: avgpool_formula -- (n - k) / s + 1
+    invariant avgpool2d_constraint_3
+        assert valid_input() == 2
+
+    // "Zeiler & Fergus (2014) - Visualizing and Understanding Convolutional Networks": pooling halves each side
+    invariant avgpool2d_constraint_4
+        assert calc_output_size(8) == 4
+
+    // "He et al. (2016) - Deep Residual Learning for Image Recognition": a 7 x 7 map pools to 3 x 3
+    invariant avgpool2d_constraint_5
+        assert calc_output_size(7) == 3
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/positional-encoding/card.png b/apps/website/public/learn/positional-encoding/card.png new file mode 100644 index 0000000000000000000000000000000000000000..8242a7ccf968f13c09bf3d688b24302929023356 GIT binary patch literal 65431 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 + + + + + +Positional encoding: neural networks course, lesson 25 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Positional encoding

+

You will learn

How sines and cosines at falling frequencies give every position its own vector, and why a shift is a turn.

+

Attention treats its input as a set, so the order of the words has to be added to them. The sinusoidal encoding gives each position d numbers: the sin and cos of the position times a frequency that falls by 10000^(2/d) from pair to pair. With d = 8 the four pairs turn by 1, 0.1, 0.01 and 0.001 radians per position, like the hands of four clocks: position 5 reads -0.959, 0.284 in its fast pair and 0.005, 1.000 in its slow one. Each pair has length 1, and a shift by k positions turns every pair by its own fixed angle. The spec positional_encoding.t27 computes every value.

+

Try it

Step from position 0 to 1 and watch which clock moves; then jump to 37 and find the pair that still points up.

+

Open the interactive lesson →

+
Positional encoding: how a transformer knows word order
Positional encoding: how a transformer knows word order ↗
+

Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows.

+

specs/ml/transformer/positional_encoding.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Uses sin/cos at different frequencies for each dimension | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward read an undeclared `d_model`, called `math::pow` / `math::sin` /
+// `math::cos`, computed each encoding into a local and dropped it, and grew the
+// frequency with the dimension where Vaswani et al. (2017) shrink it. It now
+// writes the sinusoidal encoding
+//   PE(pos, 2i) = sin(pos / 10000^(2i / d)),  PE(pos, 2i + 1) = cos(pos / 10000^(2i / d))
+// for each position into a positions x d_model buffer.
+
+module PositionalEnc;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_MAX_LEN : u32 = 2048;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PosEncConfig = struct {
+        d_model : u32,
+        max_len : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // 1 / 10000^(2i / d) = exp(-(2i / d) ln 10000)
+    fn inv_freq(pair: u32, d_model: u32) -> f32 {
+        return exp(-(@as(f32, @floatFromInt(2 * pair)) / @as(f32, @floatFromInt(d_model))) * log(@as(f32, 10000.0)));
+    }
+
+    fn forward(positions: []const u32, config: PosEncConfig, out: []f32) -> void {
+        var p : usize = 0;
+        while (p < positions.len) {
+            const pos : f32 = @as(f32, @floatFromInt(positions[p]));
+            var dim : u32 = 0;
+            while (dim < config.d_model) {
+                const angle = pos * inv_freq(dim / 2, config.d_model);
+                if (dim % 2 == 0) {
+                    out[p * config.d_model + dim] = sin(angle);
+                } else {
+                    out[p * config.d_model + dim] = cos(angle);
+                }
+                dim = dim + 1;
+            }
+            p = p + 1;
+        }
+    }
+
+    // PE(pos, dim) for d_model 8
+    fn pe(pos: u32, dim: usize) -> f32 {
+        const positions : [1]u32 = [pos];
+        var out : [8]f32 = [9.0] ** 8;
+        forward(&positions, PosEncConfig{ .d_model = 8, .max_len = DEFAULT_MAX_LEN }, &out);
+        return out[dim];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // pos 1, d 8: dims 0/1 use frequency 1, dims 2/3 use 1/10 (10000^(2/8) = 10)
+    test forward_basic_case
+        given s0 = pe(1, 0)
+        when s2 = pe(1, 2)
+        then @abs(s0 - 0.8414710) < 0.000001 and @abs(pe(1, 1) - 0.5403023) < 0.000001 and @abs(s2 - 0.0998334) < 0.000001 and @abs(pe(1, 3) - 0.9950042) < 0.000001
+
+    // Position 0 encodes as (0, 1, 0, 1, ...)
+    test forward_simple
+        given s = pe(0, 6)
+        when c = pe(0, 7)
+        then s == 0.0 and c == 1.0
+
+    // Each sin/cos pair lies on the unit circle
+    test forward_pairs_are_unit_vectors
+        given p = pe(37, 2) * pe(37, 2) + pe(37, 3) * pe(37, 3)
+        then @abs(p - 1.0) < 0.000001
+
+    invariant positional_encoding_max_len_is_positive
+        assert DEFAULT_MAX_LEN > 0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/ppo-and-the-reward/card.png b/apps/website/public/learn/ppo-and-the-reward/card.png new file mode 100644 index 0000000000000000000000000000000000000000..9da2e09e5f16368f7dac58b55aebbfbbdfb88102 GIT binary patch literal 53412 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/ppo-and-the-reward/index.html b/apps/website/public/learn/ppo-and-the-reward/index.html new file mode 100644 index 0000000000..636b8e51fb --- /dev/null +++ b/apps/website/public/learn/ppo-and-the-reward/index.html @@ -0,0 +1,272 @@ + + + + + + +PPO and the reward: neural networks course, lesson 27 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

PPO and the reward

+

You will learn

How PPO turns a reward into a policy update, and how its clip keeps one update from going too far.

+

An agent learns from reward by making good actions more likely. PPO measures a change of policy by the ratio r of the new probability of an action to the old one and multiplies it by the advantage A, how much better the action did than expected. Then it clips: once r has moved more than eps the way A rewards, the objective goes flat. At r = 1.5, A = 1 and eps 0.2 the raw r A is 1.5, but PPO counts 1.2, so one batch cannot push the policy far. On the spec's batch, ratios 1, 1.1 and 0.9 with advantages 2, 1.5 and 3, the policy loss is -2.1167. The spec ppo_clip_loss.t27 computes it.

+

Try it

Make the advantage negative and find where the curve goes flat now; then widen eps to 0.5.

+

Open the interactive lesson →

+
PPO: how an agent learns from reward without lurching
PPO: how an agent learns from reward without lurching ↗
+

Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling.

+

specs/ml/rl/ppo_clip_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Probability ratio between policies | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written with `let x = if ... {}` and `for i in 0..n`, so it never compiled.
+// Three formulas were wrong, and their tests pinned the wrong values:
+// - compute_ratio returned log pi_new - log pi_old; the ratio is exp of that.
+// - clipped_surrogate returned clip(r) A; PPO's term is min(r A, clip(r) A), so
+//   r = 1.1 inside the clip range gives 2.2, not 2.4.
+// - policy_loss returned the surrogate itself, a quantity to MAXIMISE; as a loss
+//   added to the value and entropy losses it is minus the mean surrogate.
+// Each test now states the value PPO defines (Schulman et al., 2017).
+
+module PpoClipLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_CLIP_EPSILON : f32 = 0.2;
+    const DEFAULT_ENTROPY_COEF : f32 = 0.01;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PPOClipConfig = struct {
+        clip_epsilon : f32,
+        entropy_coef : f32,
+        value_clip_coef : f32,
+    };
+
+    pub const PPOBatch = struct {
+        states : [][]f32,
+        actions : [][]f32,
+        old_log_probs : []f32,
+        advantages : []f32,
+        returns : []f32,
+        values : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // r = pi_new / pi_old = exp(log pi_new - log pi_old)
+    fn compute_ratio(new_log_prob: f32, old_log_prob: f32) -> f32 {
+        return exp(new_log_prob - old_log_prob);
+    }
+
+    // min(r A, clip(r, 1 - eps, 1 + eps) A)
+    fn clipped_surrogate(ratio: f32, advantage: f32, clip_epsilon: f32) -> f32 {
+        const clipped_ratio = @min(@max(ratio, 1.0 - clip_epsilon), 1.0 + clip_epsilon);
+        return @min(ratio * advantage, clipped_ratio * advantage);
+    }
+
+    // -mean_t min(r_t A_t, clip(r_t) A_t): the loss gradient descent minimises
+    fn policy_loss(ratios: []const f32, advantages: []const f32, clip_epsilon: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < ratios.len) {
+            total = total + clipped_surrogate(ratios[i], advantages[i], clip_epsilon);
+            i = i + 1;
+        }
+        return -total / @as(f32, @floatFromInt(ratios.len));
+    }
+
+    // -coef * mean entropy: lower loss for a more exploratory policy
+    fn entropy_loss(entropies: []const f32, entropy_coef: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < entropies.len) {
+            total = total + entropies[i];
+            i = i + 1;
+        }
+        return -entropy_coef * (total / @as(f32, @floatFromInt(entropies.len)));
+    }
+
+    // mean 0.5 (target - (old + clip(pred - old, -c, c)))^2
+    fn value_loss(predicted_values: []const f32, target_values: []const f32, old_values: []const f32, clip_coef: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predicted_values.len) {
+            const diff = @min(@max(predicted_values[i] - old_values[i], -clip_coef), clip_coef);
+            const err = target_values[i] - (old_values[i] + diff);
+            total = total + 0.5 * err * err;
+            i = i + 1;
+        }
+        return total / @as(f32, @floatFromInt(predicted_values.len));
+    }
+
+    fn policy_loss_of(r0: f32, r1: f32, r2: f32) -> f32 {
+        const ratios : [3]f32 = [r0, r1, r2];
+        const advantages : [3]f32 = [2.0, 1.5, 3.0];
+        return policy_loss(&ratios, &advantages, DEFAULT_CLIP_EPSILON);
+    }
+
+    fn entropy_loss_of() -> f32 {
+        const entropies : [3]f32 = [0.5, 0.6, 0.4];
+        return entropy_loss(&entropies, DEFAULT_ENTROPY_COEF);
+    }
+
+    fn value_loss_of(p0: f32) -> f32 {
+        const predicted : [3]f32 = [p0, 2.0, 1.5];
+        const target : [3]f32 = [1.1, 2.1, 1.6];
+        const old : [3]f32 = [0.9, 1.9, 1.4];
+        return value_loss(&predicted, &target, &old, 0.2);
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_CLIP_EPSILON;
+    }
+
+    // total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) → f32
+    fn total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) -> f32 {
+        // Combine all loss components
+        return policy_loss_value + value_loss_coef * value_loss_value + entropy_loss_value;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test compute_ratio_basic_case
+        given 
+            new_log_prob = 0.5
+            old_log_prob = 0.3
+        when result = compute_ratio(new_log_prob, old_log_prob)
+        then @abs(result - 1.2214028) < 0.000001  // exp(0.2); the old `== 0.2` was the log ratio
+
+    test clipped_surrogate_basic_case
+        given 
+            ratio = 1.1
+            advantage = 2.0
+            clip_epsilon = 0.2
+        when result = clipped_surrogate(ratio, advantage, clip_epsilon)
+        then @abs(result - 1.1 * 2.0) < 0.000001  // inside [0.8, 1.2] the clip does nothing
+
+    test clipped_surrogate_clipping_case
+        given 
+            ratio = 1.5  // Above clip threshold of 1.2
+            advantage = 2.0
+            clip_epsilon = 0.2
+        when result = clipped_surrogate(ratio, advantage, clip_epsilon)
+        then @abs(result - 1.2 * 2.0) < 0.000001 and clipped_surrogate(0.5, -1.0, 0.2) == -0.8
+
+    // min(r A, clip(r) A) = (2.0, 1.65, 2.7): the loss is -mean = -2.1166667. The old `> 0` was
+    // the surrogate's sign; a ratio pushed past the clip earns nothing more.
+    test policy_loss_basic_case
+        given result = policy_loss_of(1.0, 1.1, 0.9)
+        when pushed = policy_loss_of(1.0, 1.1, 3.0)
+        then result < 0.0 and @abs(result + 2.1166667) < 0.000001 and @abs(pushed - policy_loss_of(1.0, 1.1, 1.2)) < 0.000001
+
+    test entropy_loss_basic_case
+        given result = entropy_loss_of()
+        then result < 0.0 and @abs(result + 0.005) < 0.0000001
+
+    test value_loss_basic_case
+        given result = value_loss_of(1.0)
+        when clipped = value_loss_of(5.0)
+        then result > 0.0 and @abs(result - 0.005) < 0.0000001 and @abs(clipped - value_loss_of(1.1)) < 0.0000001
+
+    test total_loss_basic_case
+        given 
+            policy_loss_value = 1.0
+            value_loss_value = 0.5
+            entropy_loss_value = -0.01
+            value_loss_coef = 0.5
+        when result = total_loss(policy_loss_value, value_loss_value, entropy_loss_value, value_loss_coef)
+        then @abs(result - (1.0 + 0.5 * 0.5 + (-0.01))) < 0.0000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // 0 < clip_epsilon <= 1 (typically 0.1-0.3)
+    invariant ppo_clip_loss_constraint_0
+        assert valid_input() > 0.0 and valid_input() <= 1.0
+
+    // entropy_coef >= 0
+    invariant ppo_clip_loss_constraint_1
+        assert DEFAULT_ENTROPY_COEF >= 0.0
+
+    // name: ppo_objective -- for A > 0 the surrogate stops growing at r = 1 + eps
+    invariant ppo_clip_loss_constraint_2
+        assert clipped_surrogate(5.0, 1.0, 0.2) == 1.2
+
+    // name: probability_ratio -- equal log-probabilities give r = 1
+    invariant ppo_clip_loss_constraint_3
+        assert compute_ratio(0.3, 0.3) == 1.0
+
+    // "Schulman et al. (2017) - Proximal Policy Optimization Algorithms, arXiv:1707.06347":
+    // for A < 0 the surrogate stops falling at r = 1 - eps
+    invariant ppo_clip_loss_constraint_4
+        assert clipped_surrogate(0.1, -1.0, 0.2) == -0.8
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/relu/card.png b/apps/website/public/learn/relu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..e7c67f869de32b6d2f7bfb7952cd550a982383d1 GIT binary patch literal 54887 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 + + + + + +ReLU: keep the positive part: neural networks course, lesson 1 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

ReLU: keep the positive part

+

You will learn

What ReLU does to a positive and to a negative input, and why a slope of 0 stops a unit from learning.

+

A neuron adds up its weighted inputs and passes the sum through an activation. ReLU is the plainest one, max(0, x): a positive sum goes through unchanged and a negative one becomes 0. Its slope is 1 or 0, and a slope of 0 is a unit that has stopped learning, because no gradient flows back through it. A leaky slope fixes that: with a slope of 0.1, x = -2 gives -0.2 and passes back a gradient of 0.1. The spec relu_activation.t27 computes both curves the widget draws.

+

Try it

Put x at -2 and read the slope with and without the leak; then find the slope at x = 1.5.

+

Open the interactive lesson →

+
ReLU: what a neuron does with a negative number
ReLU: what a neuron does with a negative number ↗
+

Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through.

+

specs/ml/activation/relu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// ReLU produces sparse gradients | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the tests called forward and backward with one or two of their three or
+// four arguments, two asserted only `result != undefined`, and the invariants
+// asserted `true`. Each test now runs the functions on buffers and checks values.
+
+module Relu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const ZERO : f32 = 0.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const ReLUConfig = struct {
+        negative_slope : f32,
+        inplace : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(input: []const f32, output: []f32, config: ReLUConfig) → void
+    fn forward(input: []const f32, output: []f32, config: ReLUConfig) -> void {
+        // Values at or below ZERO take the negative branch, values above ZERO pass through
+        // For negative_slope = 0.0, this gives max(0, x) behavior
+        var i : usize = 0;
+        while (i < input.len) : (i += 1) {
+            if (input[i] > ZERO) {
+                output[i] = input[i];  // Positive branch: identity
+            } else {
+                output[i] = input[i] * config.negative_slope;  // Negative branch: scaled
+            }
+        }
+    }
+
+    // backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) → void
+    fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) -> void {
+        // The gradient gate is on the forward input, not grad_output - this makes gradients sparse
+        var i : usize = 0;
+        while (i < input.len) : (i += 1) {
+            if (input[i] > ZERO) {
+                grad_input[i] = grad_output[i];  // Positive branch: identity gradient
+            } else {
+                grad_input[i] = grad_output[i] * config.negative_slope;  // Negative branch: scaled gradient
+            }
+        }
+    }
+
+    // Note: config.inplace is declared but currently unused by these functions.
+    // The buffers are separate parameters, so the aliasing case is not handled.
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    fn cfg(slope: f32) -> ReLUConfig {
+        return ReLUConfig{ .negative_slope = slope, .inplace = false };
+    }
+
+    // output[index] of forward over (a, b, c)
+    fn forward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 {
+        const input : [3]f32 = [a, b, c];
+        var output : [3]f32 = [9.0] ** 3;
+        forward(&input, &output, cfg(slope));
+        return output[index];
+    }
+
+    // grad_input[index] of backward over (a, b, c), every grad_output 1
+    fn backward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 {
+        const grad_output : [3]f32 = [1.0, 1.0, 1.0];
+        const input : [3]f32 = [a, b, c];
+        var grad_input : [3]f32 = [9.0] ** 3;
+        backward(&grad_output, &input, &grad_input, cfg(slope));
+        return grad_input[index];
+    }
+
+    // The shared fixture: one negative, zero, one positive.
+    fn valid_input() -> f32 {
+        return -2.0;
+    }
+
+    // max(0, x) on (-2, 0, 2)
+    test "forward_basic_case"
+        given negative = forward_at(-2.0, 0.0, 2.0, 0.0, 0)
+        when positive = forward_at(-2.0, 0.0, 2.0, 0.0, 2)
+        then negative == 0.0 and forward_at(-2.0, 0.0, 2.0, 0.0, 1) == 0.0 and positive == 2.0
+
+    test "forward_positive_identity"
+        given slope = 0.0
+        when first = forward_at(1.0, 2.0, 3.0, slope, 0)
+        then first == 1.0 and forward_at(1.0, 2.0, 3.0, slope, 1) == 2.0 and forward_at(1.0, 2.0, 3.0, slope, 2) == 3.0
+
+    test "forward_negative_scaling"
+        given slope = 0.5
+        when first = forward_at(-1.0, -2.0, -3.0, slope, 0)
+        then first == -0.5 and forward_at(-1.0, -2.0, -3.0, slope, 1) == -1.0 and forward_at(-1.0, -2.0, -3.0, slope, 2) == -1.5
+
+    test "forward_zero_negative_slope"
+        given slope = 0.0
+        when first = forward_at(-1.0, 0.0, 1.0, slope, 0)
+        then first == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 1) == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0
+
+    // grad_output * negative_slope for input <= ZERO (0 included), grad_output above it
+    test "backward_input_gate"
+        given slope = 0.5
+        when first = backward_at(-1.0, 0.0, 1.0, slope, 0)
+        then first == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 1) == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0
+
+    // Plain ReLU: the gradient is 0 left of zero and passes through right of it
+    test "backward_basic_case"
+        given negative = backward_at(-2.0, 0.0, 2.0, 0.0, 0)
+        when positive = backward_at(-2.0, 0.0, 2.0, 0.0, 2)
+        then negative == 0.0 and positive == 1.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.len == output.len: forward writes every element of its buffer (none keeps the 9.0 fill)
+    invariant relu_constraint_0
+        assert forward_at(valid_input(), 0.0, 1.0, 0.0, 0) != 9.0 and forward_at(valid_input(), 0.0, 1.0, 0.0, 2) != 9.0
+
+    // A finite input gives a finite output: ReLU never exceeds its input's magnitude
+    invariant relu_constraint_1
+        assert @abs(forward_at(valid_input(), 0.0, 1.0, 0.5, 0)) <= @abs(valid_input())
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/rmsprop/card.png b/apps/website/public/learn/rmsprop/card.png new file mode 100644 index 0000000000000000000000000000000000000000..23746f9add78c65e59c6d3be8d7f7d7310119777 GIT binary patch literal 52834 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

*>$r4H9AVv-xT9Gk9-)TAroSn01lh+Qb(j=PI%^ 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/rmsprop/index.html b/apps/website/public/learn/rmsprop/index.html new file mode 100644 index 0000000000..d926639ca5 --- /dev/null +++ b/apps/website/public/learn/rmsprop/index.html @@ -0,0 +1,174 @@ + + + + + + +RMSProp: neural networks course, lesson 17 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

RMSProp

+

You will learn

How RMSProp divides each step by a running root mean square, so the step no longer depends on the gradient's size.

+

The right step size depends on the size of the gradient, and different weights see gradients a million times apart. RMSProp keeps a running mean of the squared gradient, the cache, and divides each step by its root, so the step has no units: with a constant gradient of 0.001, 0.5 or 1000 the weight moves by exactly the same 0.0316 on step 1 and walks the same path, reaching -0.0914 after 100 steps at lr 0.01. The decay sets how slowly the cache fills: at 0.99 the same 100 steps end at -1.0261. The spec rmsprop.t27 computes the weight and the cache.

+

Try it

Switch between the three gradients and check that the lines do not move; then raise the decay to 0.99.

+

Open the interactive lesson →

+
RMSProp: a step that does not care how big the gradient is
RMSProp: a step that does not care how big the gradient is ↗
+

Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends.

+

specs/ml/optimizer/rmsprop.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// RMSprop optimizer with moving average of squared gradients | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/rmsprop.tri. The port kept only
+// `grad`, squared grad[0], and threw it away; the test read an undefined
+// default_input().
+
+module Rmsprop;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_DECAY : f32 = 0.9;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const RMSpropConfig = struct {
+        learning_rate : f32,
+        decay : f32,
+        epsilon : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // step(grad, param, cache, config) -> void, in place:
+    //   cache = decay * cache + (1 - decay) * grad^2
+    //   param -= lr * grad / (sqrt(cache) + epsilon)
+    // The .tri formula reads lr, decay and epsilon but its parameter list
+    // omits them; they come from config here.
+    fn step(grad: []const f32, param: []f32, cache: []f32, config: RMSpropConfig) -> void {
+        var i : usize = 0;
+        while (i < grad.len) {
+            const g = grad[i];
+            cache[i] = config.decay * cache[i] + (1.0 - config.decay) * g * g;
+            param[i] = param[i] - config.learning_rate * g / (@sqrt(cache[i]) + config.epsilon);
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    // run `steps` steps of constant gradient g on one parameter from 1.0
+    fn param_after(g: f32, steps: usize, decay: f32) -> f32 {
+        const grad : [1]f32 = [g];
+        var param : [1]f32 = [1.0];
+        var cache : [1]f32 = [0.0];
+        var k : usize = 0;
+        while (k < steps) {
+            step(&grad, &param, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = decay, .epsilon = 0.00000001 });
+            k = k + 1;
+        }
+        return param[0];
+    }
+
+    fn cache_after(g: f32, steps: usize) -> f32 {
+        const grad : [1]f32 = [g];
+        var param : [1]f32 = [1.0];
+        var cache : [1]f32 = [0.0];
+        var k : usize = 0;
+        while (k < steps) {
+            step(&grad, &param, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = DEFAULT_DECAY, .epsilon = 0.00000001 });
+            k = k + 1;
+        }
+        return cache[0];
+    }
+
+    // first step from cache 0: cache = 0.1 g^2, so the move is lr / sqrt(0.1)
+    // = 0.0316228 whatever the size of g
+    test first_step_is_scale_free
+        given small = param_after(0.001, 1, DEFAULT_DECAY)
+        when large = param_after(1000.0, 1, DEFAULT_DECAY)
+        then @abs(small - (1.0 - 0.0316228)) < 0.00001 and @abs(large - small) < 0.00001
+
+    // moving average of a constant: cache_n = (1 - 0.9^n) g^2
+    test cache_is_moving_average
+        given result = cache_after(2.0, 3)
+        when expected = (1.0 - 0.729) * 4.0
+        then @abs(result - expected) < 0.00001
+
+    test moves_against_the_gradient
+        given up = param_after(0.5, 2, DEFAULT_DECAY)
+        when down = param_after(-0.5, 2, DEFAULT_DECAY)
+        then up < 1.0 and down > 1.0 and @abs((1.0 - up) - (down - 1.0)) < 0.00001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant rmsprop_decay_in_unit_interval
+        assert DEFAULT_DECAY > 0.0 and DEFAULT_DECAY < 1.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/sitemap.xml b/apps/website/public/learn/sitemap.xml index b7310eba0b..c00d74bcf6 100644 --- a/apps/website/public/learn/sitemap.xml +++ b/apps/website/public/learn/sitemap.xml @@ -505,4 +505,60 @@ https://t27.ai/ru/learn/a-correlator-finds-the-frame/ https://t27.ai/ru/learn/does-it-fit-and-close-timing/ https://t27.ai/ru/learn/capstone-a-filter-on-the-board/ + https://t27.ai/learn/neural-networks/ + https://t27.ai/learn/relu/ + https://t27.ai/learn/the-sigmoid/ + https://t27.ai/learn/tanh-and-saturation/ + https://t27.ai/learn/gelu/ + https://t27.ai/learn/swish-and-silu/ + https://t27.ai/learn/elu/ + https://t27.ai/learn/softmax-and-temperature/ + https://t27.ai/learn/embeddings/ + https://t27.ai/learn/dropout/ + https://t27.ai/learn/patches-of-a-picture/ + https://t27.ai/learn/max-pooling/ + https://t27.ai/learn/batch-normalisation/ + https://t27.ai/learn/mean-squared-error/ + https://t27.ai/learn/cross-entropy/ + https://t27.ai/learn/the-huber-loss/ + https://t27.ai/learn/gradient-descent/ + https://t27.ai/learn/rmsprop/ + https://t27.ai/learn/adam/ + https://t27.ai/learn/backpropagation/ + https://t27.ai/learn/learning-xor/ + https://t27.ai/learn/lamb-and-large-batches/ + https://t27.ai/learn/a-recurrent-cell/ + https://t27.ai/learn/lstm-gates/ + https://t27.ai/learn/attention/ + https://t27.ai/learn/positional-encoding/ + https://t27.ai/learn/an-encoder-block/ + https://t27.ai/learn/ppo-and-the-reward/ + https://t27.ai/ru/learn/neural-networks/ + https://t27.ai/ru/learn/relu/ + https://t27.ai/ru/learn/the-sigmoid/ + https://t27.ai/ru/learn/tanh-and-saturation/ + https://t27.ai/ru/learn/gelu/ + https://t27.ai/ru/learn/swish-and-silu/ + https://t27.ai/ru/learn/elu/ + https://t27.ai/ru/learn/softmax-and-temperature/ + https://t27.ai/ru/learn/embeddings/ + https://t27.ai/ru/learn/dropout/ + https://t27.ai/ru/learn/patches-of-a-picture/ + https://t27.ai/ru/learn/max-pooling/ + https://t27.ai/ru/learn/batch-normalisation/ + https://t27.ai/ru/learn/mean-squared-error/ + https://t27.ai/ru/learn/cross-entropy/ + https://t27.ai/ru/learn/the-huber-loss/ + https://t27.ai/ru/learn/gradient-descent/ + https://t27.ai/ru/learn/rmsprop/ + https://t27.ai/ru/learn/adam/ + https://t27.ai/ru/learn/backpropagation/ + https://t27.ai/ru/learn/learning-xor/ + https://t27.ai/ru/learn/lamb-and-large-batches/ + https://t27.ai/ru/learn/a-recurrent-cell/ + https://t27.ai/ru/learn/lstm-gates/ + https://t27.ai/ru/learn/attention/ + https://t27.ai/ru/learn/positional-encoding/ + https://t27.ai/ru/learn/an-encoder-block/ + https://t27.ai/ru/learn/ppo-and-the-reward/ diff --git a/apps/website/public/learn/softmax-and-temperature/card.png b/apps/website/public/learn/softmax-and-temperature/card.png new file mode 100644 index 0000000000000000000000000000000000000000..15b6d3bc4db026d839412853bc3d5a8515fa551e GIT binary patch literal 51069 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
t27.aiРусский
QVw?w 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 + + + + + +Softmax and temperature: neural networks course, lesson 7 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Softmax and temperature

+

You will learn

How softmax turns scores into probabilities that sum to one, and what the temperature does to them.

+

A classifier ends with one score per class, and softmax turns the scores into probabilities: exp of each score over the sum of all of them. Scores 1, 2 and 3 become 0.090, 0.245 and 0.665. Dividing the scores by a temperature first changes how sure it is: at 0.5 the top score takes 0.867, at 5 the three are 0.27, 0.33 and 0.40. A language model picks its next token from exactly this, and the temperature setting of a chat model is this T. The spec softmax.t27 subtracts the largest score first, so exp never overflows.

+

Try it

Cool the temperature to 0.1 and read the three probabilities; then make a tie and heat it.

+

Open the interactive lesson →

+
Softmax: how a network turns scores into a choice
Softmax: how a network turns scores into a choice ↗
+

Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out.

+

specs/ml/activation/softmax.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Control sharpness of distribution | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written with `range` and `math::exp`, which no spec declares, so no test
+// ever ran. backward was also wrong: it used only the Jacobian's diagonal,
+// p_i (1 - p_i), and dropped the -p_i p_j terms. It is now the full product
+// grad_input_i = p_i (g_i - sum_j g_j p_j) / temperature.
+
+module Softmax;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const ZERO : f32 = 0.0;
+    const ONE : f32 = 1.0;
+    const MIN_TEMP : f32 = 0.001;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SoftmaxConfig = struct {
+        temperature : f32,
+        axis : u32,
+        stable : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // output_i = exp((x_i - max) / T) / sum_j exp((x_j - max) / T); subtracting the max keeps exp finite
+    fn forward(logits: []const f32, output: []f32, config: SoftmaxConfig) -> void {
+        var max_val : f32 = logits[0];
+        var i : usize = 0;
+        while (i < logits.len) {
+            if (logits[i] > max_val) {
+                max_val = logits[i];
+            }
+            i = i + 1;
+        }
+        var sum : f32 = ZERO;
+        i = 0;
+        while (i < logits.len) {
+            output[i] = exp((logits[i] - max_val) / config.temperature);
+            sum = sum + output[i];
+            i = i + 1;
+        }
+        i = 0;
+        while (i < logits.len) {
+            output[i] = output[i] / sum;
+            i = i + 1;
+        }
+    }
+
+    // Vector-Jacobian product: grad_input_i = p_i (g_i - sum_j g_j p_j) / T
+    fn backward(grad_output: []const f32, probabilities: []const f32, grad_input: []f32, config: SoftmaxConfig) -> void {
+        var dot : f32 = ZERO;
+        var i : usize = 0;
+        while (i < grad_output.len) {
+            dot = dot + grad_output[i] * probabilities[i];
+            i = i + 1;
+        }
+        i = 0;
+        while (i < grad_output.len) {
+            grad_input[i] = probabilities[i] * (grad_output[i] - dot) / config.temperature;
+            i = i + 1;
+        }
+    }
+
+    fn cfg(temperature: f32) -> SoftmaxConfig {
+        return SoftmaxConfig{ .temperature = temperature, .axis = 0, .stable = true };
+    }
+
+    // output[index] of softmax over (a, b, c)
+    fn softmax_at(a: f32, b: f32, c: f32, temperature: f32, index: usize) -> f32 {
+        const logits : [3]f32 = [a, b, c];
+        var output : [3]f32 = [0.0] ** 3;
+        forward(&logits, &output, cfg(temperature));
+        return output[index];
+    }
+
+    // grad_input[index] for grad_output (0.1, 0.2, 0.3) at probabilities (0.2, 0.3, 0.5)
+    fn backward_at(index: usize) -> f32 {
+        const grad_output : [3]f32 = [0.1, 0.2, 0.3];
+        const probabilities : [3]f32 = [0.2, 0.3, 0.5];
+        var grad_input : [3]f32 = [0.0] ** 3;
+        backward(&grad_output, &probabilities, &grad_input, cfg(1.0));
+        return grad_input[index];
+    }
+
+    // L = sum_i w_i softmax(x)_i with w = (0.1, 0.2, 0.3): the loss whose gradient backward computes
+    fn weighted(a: f32, b: f32, c: f32) -> f32 {
+        return 0.1 * softmax_at(a, b, c, 1.0, 0) + 0.2 * softmax_at(a, b, c, 1.0, 1) + 0.3 * softmax_at(a, b, c, 1.0, 2);
+    }
+
+    fn grad_at(a: f32, b: f32, c: f32, index: usize) -> f32 {
+        const grad_output : [3]f32 = [0.1, 0.2, 0.3];
+        var probabilities : [3]f32 = [0.0] ** 3;
+        const logits : [3]f32 = [a, b, c];
+        forward(&logits, &probabilities, cfg(1.0));
+        var grad_input : [3]f32 = [0.0] ** 3;
+        backward(&grad_output, &probabilities, &grad_input, cfg(1.0));
+        return grad_input[index];
+    }
+
+    fn valid_input() -> f32 {
+        return 3.0;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // softmax(1, 2, 3) = (0.0900306, 0.2447285, 0.6652410)
+    test "forward_basic_case"
+        given p0 = softmax_at(1.0, 2.0, 3.0, 1.0, 0)
+        when p2 = softmax_at(1.0, 2.0, 3.0, 1.0, 2)
+        then p0 > 0.0 and softmax_at(1.0, 2.0, 3.0, 1.0, 1) > 0.0 and p2 > 0.0 and @abs(p0 + softmax_at(1.0, 2.0, 3.0, 1.0, 1) + p2 - 1.0) < 0.0001 and @abs(p0 - 0.0900306) < 0.000001 and @abs(p2 - 0.6652410) < 0.000001
+
+    // Subtracting the max: logits of 1000 do not overflow exp
+    test "forward_large_logits_stay_finite"
+        given p = softmax_at(1000.0, 1000.0, 1000.0, 1.0, 1)
+        then @abs(p - 1.0 / 3.0) < 0.000001
+
+    // A higher temperature flattens the distribution toward uniform
+    test "forward_temperature_flattens"
+        given sharp = softmax_at(1.0, 2.0, 3.0, 1.0, 2)
+        when flat = softmax_at(1.0, 2.0, 3.0, 10.0, 2)
+        then flat < sharp and flat > 1.0 / 3.0
+
+    // dot = 0.23: grad = (0.2 (0.1 - 0.23), 0.3 (0.2 - 0.23), 0.5 (0.3 - 0.23)) = (-0.026, -0.009, 0.035)
+    test "backward_basic_case"
+        given g0 = backward_at(0)
+        when g2 = backward_at(2)
+        then g0 != 0.0 and backward_at(1) != 0.0 and g2 != 0.0 and @abs(g0 - (-0.026)) < 0.000001 and @abs(backward_at(1) - (-0.009)) < 0.000001 and @abs(g2 - 0.035) < 0.000001
+
+    // The gradient of a function of probabilities that sum to 1 sums to 0
+    test "backward_sums_to_zero"
+        given total = backward_at(0) + backward_at(1) + backward_at(2)
+        then @abs(total) < 0.0000001
+
+    test "backward_matches_finite_difference"
+        given slope = (weighted(1.0, 2.0 + 0.001, 3.0) - weighted(1.0, 2.0 - 0.001, 3.0)) / 0.002
+        when result = grad_at(1.0, 2.0, 3.0, 1)
+        then @abs(result - slope) < 0.0005
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // logits.size() == output.size(): the first and last element are both probabilities
+    invariant softmax_constraint_0
+        assert softmax_at(1.0, 2.0, valid_input(), 1.0, 0) >= 0.0 and softmax_at(1.0, 2.0, valid_input(), 1.0, 2) >= 0.0
+
+    // config.temperature >= MIN_TEMP
+    invariant softmax_constraint_1
+        assert cfg(1.0).temperature >= MIN_TEMP
+
+    // sum(output) = 1.0 within floating precision
+    invariant softmax_constraint_2
+        assert @abs(softmax_at(1.0, 2.0, valid_input(), 1.0, 0) + softmax_at(1.0, 2.0, valid_input(), 1.0, 1) + softmax_at(1.0, 2.0, valid_input(), 1.0, 2) - 1.0) < 0.0001
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/swish-and-silu/card.png b/apps/website/public/learn/swish-and-silu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..645db828e79465a430edcbe5407e1a040b186749 GIT binary patch literal 52424 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/swish-and-silu/index.html b/apps/website/public/learn/swish-and-silu/index.html new file mode 100644 index 0000000000..03dada9adc --- /dev/null +++ b/apps/website/public/learn/swish-and-silu/index.html @@ -0,0 +1,210 @@ + + + + + + +Swish and SiLU: neural networks course, lesson 5 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

Swish and SiLU

+

You will learn

How x times sigmoid(beta x) gates itself, and how one parameter moves it from a smooth curve to ReLU.

+

Swish is x times sigmoid(beta x), a unit that gates itself. At beta 1 it is called SiLU, and its lowest point is -0.2785 near x = -1.28. Raise beta and the gate sharpens: at beta 8 the curve is ReLU with rounded corners; at beta 0.5 it is a gentle slope through zero. One parameter moves the unit between a smooth curve and a switch, and a network can learn it. The spec silu_swish_activation.t27 computes the curve and its slope for any beta, and its own batch at -2, 0 and 2: -0.238, 0 and 1.762.

+

Try it

Hold x at -1.28 and raise beta from 1 to 8; then find the beta at which the dip is gone at this scale.

+

Open the interactive lesson →

+
Swish: one knob between a smooth curve and ReLU
Swish: one knob between a smooth curve and ReLU ↗
+

Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2.

+

specs/ml/activation/silu_swish_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// SiLU derivative | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward_batch returned its input unchanged, beta was never read, and the
+// invariants asserted `true` over an undeclared `valid_input`. SiLU is now
+// x * sigmoid(beta * x) (Swish; beta = 1 is SiLU) on scalars and in place on slices.
+
+module SiluSwish;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_BETA : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SiLUConfig = struct {
+        beta : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // sigmoid(z) = 1 / (1 + exp(-z))
+    fn sigmoid(z: f32) -> f32 {
+        return 1.0 / (1.0 + exp(-z));
+    }
+
+    // Swish(x) = x * sigmoid(beta * x); beta = 1 is SiLU
+    fn forward(x: f32, beta: f32) -> f32 {
+        return x * sigmoid(beta * x);
+    }
+
+    // forward on each element IN PLACE; returns the same slice
+    fn forward_batch(input: []f32, beta: f32) -> []f32 {
+        var i : usize = 0;
+        while (i < input.len) {
+            input[i] = forward(input[i], beta);
+            i = i + 1;
+        }
+        return input;
+    }
+
+    // d/dx x sigmoid(beta x) = s + beta x s (1 - s), s = sigmoid(beta x)
+    fn derivative(x: f32, beta: f32) -> f32 {
+        const s = sigmoid(beta * x);
+        return s + beta * x * s * (1.0 - s);
+    }
+
+    fn batch_at(a: f32, b: f32, c: f32, index: usize) -> f32 {
+        var input : [3]f32 = [a, b, c];
+        const output = forward_batch(&input, DEFAULT_BETA);
+        return output[index];
+    }
+
+    fn valid_input() -> f32 {
+        return 2.0;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test "forward_basic_case"
+        given input = 0.0, beta = 1.0
+        when result = forward(input, beta)
+        then result == 0.0  // SiLU(0) = 0 * sigmoid(0) = 0
+
+    test "forward_positive_case"
+        given input = 1.0, beta = 1.0
+        when result = forward(input, beta)
+        then result > 0.0  // SiLU(1) = 1 * sigmoid(1) > 0
+
+    test "forward_negative_case"
+        given input = -1.0, beta = 1.0
+        when result = forward(input, beta)
+        then result < 0.0  // SiLU(-1) = -1 * sigmoid(-1) < 0
+
+    test "forward_batch_basic_case"
+        given beta = 1.0
+        when result = batch_at(1.0, 2.0, 3.0, 2)
+        then @abs(result - forward(3.0, beta)) < 0.0000001 and @abs(batch_at(1.0, 2.0, 3.0, 0) - 0.7310586) < 0.000001
+
+    test "forward_batch_zero_case"
+        given beta = 1.0
+        when result = batch_at(0.0, 0.0, 0.0, 0)
+        then result == 0.0 and batch_at(0.0, 0.0, 0.0, 1) == 0.0 and batch_at(0.0, 0.0, 0.0, 2) == 0.0  // SiLU(0) = 0
+
+    test "derivative_basic_case"
+        given input = 0.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU'(0) = sigmoid(0) + 0 * sigmoid(0) * (1 - sigmoid(0)) = sigmoid(0) > 0
+
+    test "derivative_positive_case"
+        given input = 1.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU derivative should be positive for positive inputs
+
+    test "derivative_negative_case"
+        given input = -1.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU derivative should be positive for negative inputs too
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // beta > 0
+    invariant silu_swish_constraint_0
+        assert DEFAULT_BETA > 0.0
+
+    // name: silu_formula -- x * sigmoid(x), so SiLU(x) - SiLU(-x) = x
+    invariant silu_swish_constraint_1
+        assert @abs(forward(valid_input(), DEFAULT_BETA) - forward(-valid_input(), DEFAULT_BETA) - valid_input()) < 0.000001
+
+    // name: derivative -- sigmoid(0) = 0.5 at the origin
+    invariant silu_swish_constraint_2
+        assert derivative(0.0, DEFAULT_BETA) == 0.5
+
+    // "Elfwing et al. (2017) - Sigmoid-Weighted Linear Units for Neural Network Function Approximation":
+    // SiLU dips below zero left of the origin
+    invariant silu_swish_constraint_3
+        assert forward(-valid_input(), DEFAULT_BETA) < 0.0
+
+    // "Ramachandran et al. (2017) - Searching for Activation Functions (Swish)": a large beta
+    // approaches ReLU
+    invariant silu_swish_constraint_4
+        assert @abs(forward(valid_input(), 50.0) - valid_input()) < 0.000001
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/tanh-and-saturation/card.png b/apps/website/public/learn/tanh-and-saturation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..84a39f5a45dd1f5600c64107a9793e92ff85bc13 GIT binary patch literal 47974 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/tanh-and-saturation/index.html b/apps/website/public/learn/tanh-and-saturation/index.html new file mode 100644 index 0000000000..bd71bc48b3 --- /dev/null +++ b/apps/website/public/learn/tanh-and-saturation/index.html @@ -0,0 +1,171 @@ + + + + + + +tanh and saturation: neural networks course, lesson 3 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

tanh and saturation

+

You will learn

Why tanh is centred on zero, and where its slope falls so low that a unit stops learning.

+

tanh is a sigmoid stretched to -1..1 and centred on 0, so a layer of tanh units passes on values that average near zero, and its slope reaches 1 at the centre. It still saturates: at 2.5 the output is 0.9866 and the slope only 0.0266. The red band marks every input where the slope is under 0.1, beyond about 1.8 on either side, and a unit whose inputs live there barely learns. The spec tanh_activation.t27 computes the curve, the slope and its own batch, tanh of 0, 1 and 2: 0, 0.762 and 0.964.

+

Try it

Drag x until the band starts and read the slope there; then compare the slope at 0 and at 2.5.

+

Open the interactive lesson →

+
tanh: where a neuron stops learning
tanh: where a neuron stops learning ↗
+

Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped.

+

specs/ml/activation/tanh_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative (can compute from output) | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: `math::exp` named a module this spec never imports, and
+// forward_batch allocated with `[]f32{input.len}`. tanh is now computed in the
+// form that cannot overflow: exp(2|x|) reaches inf in f32 at |x| = 45, and
+// inf / inf is NaN.
+
+module Tanh;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const TanhConfig = struct {
+        none : void,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // tanh(x) = (1 - e^(-2|x|)) / (1 + e^(-2|x|)), with the sign of x
+    fn forward(x: f32) -> f32 {
+        if (x < 0.0) {
+            return -forward(-x);
+        }
+        const t = exp(-2.0 * x);
+        return (1.0 - t) / (1.0 + t);
+    }
+
+    // forward_batch: output[i] = tanh(input[i])
+    fn forward_batch(input: []const f32, output: []f32) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = forward(input[i]);
+            i = i + 1;
+        }
+    }
+
+    // tanh'(x) = 1 - tanh(x)^2
+    fn derivative(x: f32) -> f32 {
+        const tanh_x = forward(x);
+        return 1.0 - (tanh_x * tanh_x);
+    }
+
+    // Given y = tanh(x), the derivative is 1 - y^2
+    fn derivative_from_output(tanh_x: f32) -> f32 {
+        return 1.0 - (tanh_x * tanh_x);
+    }
+
+    fn batch_at(index: usize) -> f32 {
+        const input : [3]f32 = [0.0, 1.0, 2.0];
+        var output : [3]f32 = [0.0] ** 3;
+        forward_batch(&input, &output);
+        return output[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // tanh(0) = 0, tanh(1) = 0.7615942, tanh is odd
+    test forward_basic_case
+        given input = 0.0
+        when result = forward(input)
+        then result == 0.0 and @abs(forward(1.0) - 0.7615942) < 0.000001 and forward(-1.0) == -forward(1.0)
+
+    // exp(2x) is inf in f32 here; the stable form still gives 1, not NaN
+    test forward_saturates_without_overflow
+        given input = 100.0
+        when result = forward(input)
+        then result == 1.0 and forward(-100.0) == -1.0
+
+    test forward_batch_basic_case
+        given first = batch_at(0)
+        when second = batch_at(1)
+        then first == 0.0 and second > 0.0 and second < 1.0 and batch_at(2) > second
+
+    test derivative_basic_case
+        given input = 0.0
+        when result = derivative(input)
+        then result == 1.0
+
+    test derivative_from_output_basic_case
+        given input = 0.5
+        when tanh_result = forward(input)
+        then derivative_from_output(tanh_result) > 0.0 and derivative_from_output(tanh_result) < 1.0 and derivative_from_output(tanh_result) == derivative(input)
+
+    test derivative_matches_finite_difference
+        given slope = (forward(0.5 + 0.001) - forward(0.5 - 0.001)) / 0.002
+        when result = derivative(0.5)
+        then @abs(result - slope) < 0.001
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/the-huber-loss/card.png b/apps/website/public/learn/the-huber-loss/card.png new file mode 100644 index 0000000000000000000000000000000000000000..da52638b159d5983049f54f2112172304df76dba GIT binary patch literal 51258 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/the-huber-loss/index.html b/apps/website/public/learn/the-huber-loss/index.html new file mode 100644 index 0000000000..85131d12a3 --- /dev/null +++ b/apps/website/public/learn/the-huber-loss/index.html @@ -0,0 +1,169 @@ + + + + + + +The Huber loss: neural networks course, lesson 15 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiРусский
+
+ +

The Huber loss

+

You will learn

How the Huber loss treats a small error like squared error and a large one linearly, so outliers pull less.

+

Squared error lets one outlier dominate: an error of 3 costs 4.5 as half its square, as much as 36 errors of 0.5. Huber is half the square while |e| is within delta and then grows only linearly, delta |e| - delta^2 / 2, so with delta 1 that error costs 2.5. The two pieces meet with the same value and slope, and the gradient never grows past delta: a far-off point pulls on the model with a bounded force. For the spec's pair of errors 0.5 and 3 the mean is 1.3125, against 2.3125 for half the square. The spec huber_loss.t27 computes both.

+

Try it

Set delta to 0.5 and drag the error to 3; then find where the two curves part.

+

Open the interactive lesson →

+
Huber loss: a loss that does not panic at an outlier
Huber loss: a loss that does not panic at an outlier ↗
+

Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square.

+

specs/ml/loss/huber_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Threshold where loss changes from quadratic to linear | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/huber_loss.tri: the port kept only
+// the first parameter and returned void, so forward computed a value and
+// threw it away, and every test asserted `result != undefined`.
+
+module HuberLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const HuberLossConfig = struct {
+        delta : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // per element e = prediction - target:
+    //   |e| <= delta: 0.5 e^2      else: delta |e| - 0.5 delta^2
+    fn element_loss(e: f32, delta: f32) -> f32 {
+        const a = @abs(e);
+        if (a <= delta) {
+            return 0.5 * e * e;
+        }
+        return delta * a - 0.5 * delta * delta;
+    }
+
+    // forward(predictions, targets, delta) -> f32. The .tri gives the
+    // per-element formula only; this returns the MEAN over elements
+    // (PyTorch HuberLoss default reduction). 0 for n = 0.
+    fn forward(predictions: []const f32, targets: []const f32, delta: f32) -> f32 {
+        if (predictions.len == 0) {
+            return 0.0;
+        }
+        var sum_loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            sum_loss = sum_loss + element_loss(predictions[i] - targets[i], delta);
+            i = i + 1;
+        }
+        return sum_loss / (predictions.len as f32);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    fn huber_one(e: f32, delta: f32) -> f32 {
+        const predictions : [1]f32 = [e];
+        const targets : [1]f32 = [0.0];
+        return forward(&predictions, &targets, delta);
+    }
+
+    test quadratic_inside_delta
+        given result = huber_one(0.5, 1.0)
+        when negative = huber_one(-0.5, 1.0)
+        then @abs(result - 0.125) < 0.000001 and result == negative
+
+    // delta |e| - delta^2 / 2 = 3 - 0.5
+    test linear_outside_delta
+        given result = huber_one(3.0, 1.0)
+        when wide = huber_one(3.0, 2.0)
+        then @abs(result - 2.5) < 0.000001 and @abs(wide - 4.0) < 0.000001
+
+    // the two pieces meet with equal value and slope at |e| = delta
+    test continuous_at_delta
+        given below = huber_one(0.999, 1.0)
+        when above = huber_one(1.001, 1.0)
+        then @abs(above - below - 0.002) < 0.0001
+
+    // mean of (0.125, 2.5) over two elements
+    fn huber_two(e0: f32, e1: f32, delta: f32) -> f32 {
+        const predictions : [2]f32 = [e0 + 1.0, e1 + 1.0];
+        const targets : [2]f32 = [1.0, 1.0];
+        return forward(&predictions, &targets, delta);
+    }
+
+    test forward_mean
+        given result = huber_two(0.5, 3.0, 1.0)
+        when expected = 1.3125
+        then @abs(result - expected) < 0.000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant huber_zero_at_target
+        assert huber_one(0.0, 1.0) == 0.0
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/learn/the-sigmoid/card.png b/apps/website/public/learn/the-sigmoid/card.png new file mode 100644 index 0000000000000000000000000000000000000000..ee7366043c377536ecb1d8cec467411dac1ac2a8 GIT binary patch literal 54034 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

+SXre9Ug$zuijxA}{OxG5 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 Y*FRDg^yE39NCqCNN}7rl@^3@_7r#!UR{#J2 literal 0 HcmV?d00001 diff --git a/apps/website/public/learn/the-sigmoid/index.html b/apps/website/public/learn/the-sigmoid/index.html new file mode 100644 index 0000000000..79977d8eed --- /dev/null +++ b/apps/website/public/learn/the-sigmoid/index.html @@ -0,0 +1,171 @@ + + + + + + +The sigmoid: a number into a probability: neural networks course, lesson 2 of 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiРусский
+
+ +

The sigmoid: a number into a probability

+

You will learn

How the sigmoid maps any input to a probability, and why its slope limits deep networks.

+

The sigmoid 1 / (1 + e^-x) squeezes the whole number line into 0 to 1, which is why it reads as a probability: 2 becomes 0.8808 and -4 becomes 0.018. Its slope is s (1 - s), computed from the output s itself, and it is largest at 0, where it is 0.25; at x = 8 it is 0.000335. A gradient that passes back through a stack of sigmoids is multiplied by at most 0.25 at each one, which is why deep sigmoid networks trained slowly. The spec sigmoid_activation.t27 computes the curve and the slope.

+

Try it

Find the input where the probability is 0.5; then drag to 6 and read how little slope is left.

+

Open the interactive lesson →

+
Sigmoid: turn any number into a probability
Sigmoid: turn any number into a probability ↗
+

Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends.

+

specs/ml/activation/sigmoid_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative (compute from output) | φ² + 1/φ² = 3 | TRINITY
+
+module Sigmoid;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SigmoidConfig = struct {
+        none : void,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(x: f32) → f32
+    fn forward(x: f32) -> f32 {
+        // Numerically stable split to avoid overflow:
+        // For x >= 0: 1 / (1 + exp(-x))
+        // For x < 0: exp(x) / (1 + exp(x))
+        // Both branches are mathematically equivalent but the second avoids exp(large positive)
+        if (x >= 0.0) {
+            return 1.0 / (1.0 + @exp(-x));
+        } else {
+            return @exp(x) / (1.0 + @exp(x));
+        }
+    }
+
+    // forward_batch(input: []f32) → []f32
+    fn forward_batch(input: []f32) -> []f32 {
+        // In-place map over input: alias input and return it
+        // This is safe because we're only reading from input and writing to the same locations
+        let i = 0;
+        while (i < input.len) {
+            input[i] = forward(input[i]);
+            i += 1;
+        }
+        return input;
+    }
+
+    // derivative(sigmoid_x: f32) → f32
+    fn derivative(sigmoid_x: f32) -> f32 {
+        // Derivative computed from output: σ'(x) = σ(x) * (1 - σ(x))
+        return sigmoid_x * (1.0 - sigmoid_x);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // #8980: through a function, so the check runs and is counted (it folded at compile
+    // time before, and the report counted it as a vacuous pass).
+    fn config_size() -> usize {
+        return @sizeOf(SigmoidConfig);
+    }
+
+    test sigmoid_has_no_tunable_parameter
+        given size = config_size()
+        then size == 0
+
+    // sigmoid_config_is_a_placeholder_not_an_empty_struct read std.meta.fields, which t27
+    // cannot lower; the parser discarded it. The test above already pins @sizeOf == 0.
+
+    test forward_at_zero_is_one_half
+        given y = forward(0.0)
+        then @abs(y - 0.5) < 1e-6
+
+    test forward_confined_to_unit_interval
+        given pos_large = forward(10.0)
+        given neg_large = forward(-10.0)
+        then (pos_large > 0.0) and (pos_large < 1.0) and (neg_large > 0.0) and (neg_large < 1.0)
+
+    test derivative_at_zero_is_maximum
+        given dy = derivative(forward(0.0))
+        then @abs(dy - 0.25) < 1e-6
+
+    test forward_batch_preserves_length
+        given input = []f32{0.0, 1.0, -1.0, 2.0, -2.0}
+        given result = forward_batch(input)
+        then result.len == input.len
+
+    // sigmoid(-x) = 1 - sigmoid(x); sigmoid(2) = 0.8807971
+    test forward_is_symmetric_about_one_half
+        given up = forward(2.0)
+        when down = forward(-2.0)
+        then @abs(up + down - 1.0) < 0.000001 and @abs(up - 0.8807971) < 0.000001
+
+    // The negative branch never computes exp(+x): no overflow at -100
+    test forward_far_left_is_zero_not_nan
+        given y = forward(-100.0)
+        then y >= 0.0 and y < 0.000001
+

Open the lesson's spec in the player ↗

+ +

All lessons

+ +
+ + + diff --git a/apps/website/public/ru/learn/a-recurrent-cell/card.png b/apps/website/public/ru/learn/a-recurrent-cell/card.png new file mode 100644 index 0000000000000000000000000000000000000000..98a7e2d190f9124dfb429d810c112acf0d7e83f6 GIT binary patch literal 54378 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

;Z%WRg5Qx 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 + + + + + +Рекуррентная ячейка: курс о нейросетях, урок 22 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Рекуррентная ячейка

+

Вы узнаете

Как рекуррентная ячейка переносит состояние от шага к шагу и почему эта память затухает.

+

Предложение приходит по одному слову, и рекуррентная ячейка переносит состояние h от шага к шагу: h' = tanh(W_x x + W_h h + b). В крошечной ячейке спеки W_x равен 1, а W_h 0.5, поэтому один импульс даёт 0.7616, 0.3634 и 0.1797: память о нём примерно вдвое слабеет каждый шаг. Второй импульс на шаге 3 поднимает h до 0.7968, чуть выше, чем начинался одиночный импульс, потому что старая память ещё там. После 8 шагов остаётся лишь 0.0466. Это затухание и есть причина, по которой простые ячейки забывают длинный контекст. Спека rnn_cell.t27 вычисляет каждый шаг.

+

Попробовать

Загрузите один импульс и прочитайте, за сколько шагов он падает ниже 0.1; затем сделайте вход чередующимся.

+

Открыть интерактивный урок →

+
Recurrent cells: how a network remembers a moment ago
Recurrent cells: how a network remembers a moment ago ↗
+

Tap the inputs of eight steps: the cell feeds its own last output back, h' = tanh(x + 0.5 h), so every pulse echoes on and fades by about half a step. Two pulses add up.

+

specs/ml/recurrent/rnn_cell.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Basic RNN recurrence equation | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written against undeclared `matmul`, `add`, `zeros`, `len` and `append`,
+// it applied tanh twice (h = tanh(tanh(z))), and the tests asserted
+// `result != undefined`. It is now the Elman cell,
+// h' = tanh(W_x x + W_h h + b), with W_x hidden x input and W_h hidden x hidden
+// (row-major), stepping over buffers the caller owns.
+
+module RnnCell;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_INPUT_SIZE : u32 = 128;
+    const DEFAULT_HIDDEN_SIZE : u32 = 128;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const RNNCellConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+    };
+
+    pub const RNNState = struct {
+        hidden : []f32,
+        cell : []f32,
+    };
+
+    pub const RNNParams = struct {
+        w_x : []f32,
+        w_h : []f32,
+        b : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // new_hidden[i] = tanh(sum_j W_x[i][j] x[j] + sum_k W_h[i][k] h[k] + b[i])
+    fn forward_step(input: []const f32, hidden: []const f32, params: RNNParams, config: RNNCellConfig, new_hidden: []f32) -> void {
+        var i : usize = 0;
+        while (i < config.hidden_size) {
+            var z : f32 = params.b[i];
+            var j : usize = 0;
+            while (j < config.input_size) {
+                z = z + params.w_x[i * config.input_size + j] * input[j];
+                j = j + 1;
+            }
+            var k : usize = 0;
+            while (k < config.hidden_size) {
+                z = z + params.w_h[i * config.hidden_size + k] * hidden[k];
+                k = k + 1;
+            }
+            new_hidden[i] = tanh(z);
+            i = i + 1;
+        }
+    }
+
+    // inputs: steps x input_size; outputs: steps x hidden_size, row t = h after step t.
+    // The state starts at initial_state and each step reads the previous row.
+    fn forward_sequence(inputs: []const f32, steps: usize, initial_state: []const f32, params: RNNParams, config: RNNCellConfig, outputs: []f32) -> void {
+        const n_in : usize = config.input_size;
+        const n_h : usize = config.hidden_size;
+        var t : usize = 0;
+        while (t < steps) {
+            if (t == 0) {
+                forward_step(inputs[0..n_in], initial_state, params, config, outputs[0..n_h]);
+            } else {
+                forward_step(inputs[t * n_in .. (t + 1) * n_in], outputs[(t - 1) * n_h .. t * n_h], params, config, outputs[t * n_h .. (t + 1) * n_h]);
+            }
+            t = t + 1;
+        }
+    }
+
+    // The first hidden_size entries of `buffer`, zeroed
+    fn init_state(buffer: []f32, hidden_size: u32) -> []f32 {
+        var i : usize = 0;
+        while (i < hidden_size) {
+            buffer[i] = 0.0;
+            i = i + 1;
+        }
+        return buffer[0..hidden_size];
+    }
+
+    // A 1-in, 1-hidden cell with W_x = 1, W_h = 0.5, b = 0: h' = tanh(x + 0.5 h)
+    fn tiny() -> RNNCellConfig {
+        return RNNCellConfig{ .input_size = 1, .hidden_size = 1 };
+    }
+
+    fn tiny_step(x: f32, h: f32) -> f32 {
+        var w_x : [1]f32 = [1.0];
+        var w_h : [1]f32 = [0.5];
+        var b : [1]f32 = [0.0];
+        const input : [1]f32 = [x];
+        const hidden : [1]f32 = [h];
+        var out : [1]f32 = [9.0];
+        forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &out);
+        return out[0];
+    }
+
+    // The sequence (1, 0, 0) from h = 0: h after step t
+    fn tiny_sequence(t: usize) -> f32 {
+        var w_x : [1]f32 = [1.0];
+        var w_h : [1]f32 = [0.5];
+        var b : [1]f32 = [0.0];
+        const inputs : [3]f32 = [1.0, 0.0, 0.0];
+        const h0 : [1]f32 = [0.0];
+        var outputs : [3]f32 = [9.0] ** 3;
+        forward_sequence(&inputs, 3, &h0, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, tiny(), &outputs);
+        return outputs[t];
+    }
+
+    // A 2-in, 2-hidden cell: h' = tanh(W_x x + W_h h + b) with W_x = [[1, -1], [0.5, 0.5]],
+    // W_h = [[0.1, 0], [0, 0.1]], b = (0, -0.5), at x = (1, 2), h = (1, -1)
+    fn wide_step(index: usize) -> f32 {
+        var w_x : [4]f32 = [1.0, -1.0, 0.5, 0.5];
+        var w_h : [4]f32 = [0.1, 0.0, 0.0, 0.1];
+        var b : [2]f32 = [0.0, -0.5];
+        const input : [2]f32 = [1.0, 2.0];
+        const hidden : [2]f32 = [1.0, -1.0];
+        var out : [2]f32 = [9.0] ** 2;
+        forward_step(&input, &hidden, RNNParams{ .w_x = &w_x, .w_h = &w_h, .b = &b }, RNNCellConfig{ .input_size = 2, .hidden_size = 2 }, &out);
+        return out[index];
+    }
+
+    fn init_len(hidden_size: u32) -> usize {
+        var buffer : [64]f32 = [9.0] ** 64;
+        const h = init_state(&buffer, hidden_size);
+        if (h[hidden_size - 1] != 0.0) {
+            return 0;
+        }
+        return h.len;
+    }
+
+    fn valid_input() -> f32 {
+        return tiny_step(1.0, 0.0);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // z = (1 - 2 + 0.1, 0.5 + 1 - 0.1 - 0.5) = (-0.9, 0.9): h' = (tanh(-0.9), tanh(0.9))
+    test forward_step_basic_case
+        given h0 = wide_step(0)
+        when h1 = wide_step(1)
+        then @abs(h0 + 0.7162979) < 0.000001 and @abs(h1 - 0.7162979) < 0.000001 and @abs(tiny_step(1.0, 0.0) - 0.7615942) < 0.000001
+
+    // The cell remembers: after the input pulse, h decays through the recurrent weight,
+    // h1 = tanh(1), h2 = tanh(0.5 h1), h3 = tanh(0.5 h2)
+    test forward_sequence_basic_case
+        given h1 = tiny_sequence(0)
+        when h3 = tiny_sequence(2)
+        then @abs(h1 - 0.7615942) < 0.000001 and @abs(tiny_sequence(1) - tanh(0.5 * h1)) < 0.000001 and @abs(h3 - tanh(0.5 * tiny_sequence(1))) < 0.000001 and h3 > 0.0 and h3 < tiny_sequence(1)
+
+    test init_state_basic_case
+        given hidden_size = 64
+        when result = init_len(hidden_size)
+        then result == hidden_size
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input_size >= 1
+    invariant rnn_cell_constraint_0
+        assert DEFAULT_INPUT_SIZE >= 1
+
+    // hidden_size >= 1
+    invariant rnn_cell_constraint_1
+        assert DEFAULT_HIDDEN_SIZE >= 1
+
+    // name: rnn_formula -- one tanh, not two: tanh(1) = 0.7615942, tanh(tanh(1)) = 0.6420
+    invariant rnn_cell_constraint_2
+        assert valid_input() > 0.76 and valid_input() < 0.77
+
+    // "Elman (1990) - Finding Structure in Time": the state carries the past forward
+    invariant rnn_cell_constraint_3
+        assert tiny_step(0.0, 1.0) > 0.0
+
+    // "Goodfellow et al. (2016) - Sequence Modeling with RNNs and LSTMs": tanh bounds the state
+    invariant rnn_cell_constraint_4
+        assert tiny_step(100.0, 1.0) <= 1.0 and tiny_step(-100.0, -1.0) >= -1.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/adam/card.png b/apps/website/public/ru/learn/adam/card.png new file mode 100644 index 0000000000000000000000000000000000000000..ee1826e16318b66fe7be43c6b217161105558129 GIT binary patch literal 64282 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 N1zA;@idU~c{1;`fNihHb literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/adam/index.html b/apps/website/public/ru/learn/adam/index.html new file mode 100644 index 0000000000..14f378e07b --- /dev/null +++ b/apps/website/public/ru/learn/adam/index.html @@ -0,0 +1,232 @@ + + + + + + +Adam: момент и масштаб: курс о нейросетях, урок 18 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Adam: момент и масштаб

+

Вы узнаете

Как Adam соединяет момент со скользящим масштабом и почему поправка смещения делает шаг 1 фиксированного размера.

+

Adam соединяет обе идеи: m, скользящее среднее градиента, как в моменте, и v, скользящее среднее его квадрата, как в RMSProp; шаг равен lr m / sqrt(v). Оба начинают с 0 и поначалу слишком малы, поэтому Adam делит их на 1 - beta^t, и на шаге 1 это делает сдвиг ровно lr, умноженным на знак градиента: градиенты 2, -40 и 0.5 сдвигают свои веса на одинаковые 0.001. На чаше спеки (x - 3)^2 при lr 0.1 Adam поднимается от 0, перелетает примерно до 3.18 и успокаивается на 3.00005 к шагу 200. Спека adam.t27 вычисляет каждый шаг.

+

Попробовать

Дайте трём градиентам очень разные размеры и прочитайте веса после шага 1; затем найдите, где путь достигает вершины.

+

Открыть интерактивный урок →

+
Adam: the optimizer most networks are trained with
Adam: the optimizer most networks are trained with ↗
+

Watch Adam carry a weight from 0 to the minimum at 3, then set three gradients of any size: the bias correction makes the first step lr times their sign, whatever their size.

+

specs/ml/optimizer/adam.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Adam adapts learning rate per parameter | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: step only checked its gradients with an undeclared `math::is_finite`
+// and updated nothing; the tests asserted `result != undefined`. step is now
+// Adam (Kingma and Ba, 2015) with bias correction. It refuses (returns false,
+// changes nothing) when a gradient is NaN or infinite, which is what the old body
+// validated.
+
+module Adam;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_BETA1 : f32 = 0.9;
+    const DEFAULT_BETA2 : f32 = 0.999;
+    const DEFAULT_EPSILON : f32 = 1e-8;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const AdamConfig = struct {
+        learning_rate : f32,
+        beta1 : f32,
+        beta2 : f32,
+        epsilon : f32,
+        weight_decay : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // b^t for a whole t >= 0
+    fn powi(b: f32, t: u32) -> f32 {
+        var r : f32 = 1.0;
+        var n : u32 = 0;
+        while (n < t) {
+            r = r * b;
+            n = n + 1;
+        }
+        return r;
+    }
+
+    // NaN is the one value not equal to itself; inf - inf is NaN
+    fn is_finite(x: f32) -> bool {
+        return x == x and (x - x) == (x - x);
+    }
+
+    // One Adam step number t (1-based) over params, with moment buffers m and v:
+    //   g = grad + wd p
+    //   m = b1 m + (1 - b1) g          v = b2 v + (1 - b2) g^2
+    //   m_hat = m / (1 - b1^t)          v_hat = v / (1 - b2^t)
+    //   p = p - lr m_hat / (sqrt(v_hat) + eps)
+    fn step(params: []f32, grads: []const f32, m: []f32, v: []f32, t: u32, config: AdamConfig) -> bool {
+        var i : usize = 0;
+        while (i < grads.len) {
+            if (!is_finite(grads[i])) {
+                return false;
+            }
+            i = i + 1;
+        }
+        const c1 = 1.0 - powi(config.beta1, t);
+        const c2 = 1.0 - powi(config.beta2, t);
+        i = 0;
+        while (i < params.len) {
+            const g = grads[i] + config.weight_decay * params[i];
+            m[i] = config.beta1 * m[i] + (1.0 - config.beta1) * g;
+            v[i] = config.beta2 * v[i] + (1.0 - config.beta2) * g * g;
+            const m_hat = m[i] / c1;
+            const v_hat = v[i] / c2;
+            params[i] = params[i] - config.learning_rate * m_hat / (sqrt(v_hat) + config.epsilon);
+            i = i + 1;
+        }
+        return true;
+    }
+
+    fn cfg(lr: f32) -> AdamConfig {
+        return AdamConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.0 };
+    }
+
+    // which: 0 = param, 1 = m, 2 = v after one step on params (1, 2, 3) with grads (g0, g1, g2)
+    fn first_step(g0: f32, g1: f32, g2: f32, which: u8, index: usize) -> f32 {
+        var params : [3]f32 = [1.0, 2.0, 3.0];
+        const grads : [3]f32 = [g0, g1, g2];
+        var m : [3]f32 = [0.0] ** 3;
+        var v : [3]f32 = [0.0] ** 3;
+        _ = step(&params, &grads, &m, &v, 1, cfg(0.001));
+        if (which == 1) {
+            return m[index];
+        }
+        if (which == 2) {
+            return v[index];
+        }
+        return params[index];
+    }
+
+    // a / b at run time, where IEEE gives NaN for 0 / 0 and inf for 1 / 0
+    fn ratio(a: f32, b: f32) -> f32 {
+        return a / b;
+    }
+
+    fn accepts(g: f32) -> bool {
+        var params : [1]f32 = [1.0];
+        const grads : [1]f32 = [g];
+        var m : [1]f32 = [0.0];
+        var v : [1]f32 = [0.0];
+        return step(&params, &grads, &m, &v, 1, cfg(0.001)) and params[0] != 1.0;
+    }
+
+    // Minimise (x - 3)^2 from 0
+    fn descend(steps: u32) -> f32 {
+        var params : [1]f32 = [0.0];
+        var m : [1]f32 = [0.0];
+        var v : [1]f32 = [0.0];
+        var t : u32 = 1;
+        while (t <= steps) {
+            const grads : [1]f32 = [2.0 * (params[0] - 3.0)];
+            _ = step(&params, &grads, &m, &v, t, cfg(0.1));
+            t = t + 1;
+        }
+        return params[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Bias correction makes the first step lr * sign(g), whatever |g| is
+    test step_basic_case
+        given p0 = first_step(0.1, -5.0, 0.0, 0, 0)
+        when p1 = first_step(0.1, -5.0, 0.0, 0, 1)
+        then @abs(p0 - 0.999) < 0.000001 and @abs(p1 - 2.001) < 0.000001 and first_step(0.1, -5.0, 0.0, 0, 2) == 3.0
+
+    // m = 0.1 g and v = 0.001 g^2 after the first step
+    test step_with_gradients
+        given m2 = first_step(0.1, 0.2, 0.3, 1, 2)
+        when v2 = first_step(0.1, 0.2, 0.3, 2, 2)
+        then @abs(m2 - 0.03) < 0.0000001 and @abs(v2 - 0.00009) < 0.0000001
+
+    // Finite gradients are applied; NaN and inf are refused
+    test step_validates_gradients
+        given ok = accepts(1.5) and accepts(-2.3) and accepts(4.7)
+        when refused = !accepts(ratio(0.0, 0.0)) and !accepts(ratio(1.0, 0.0))
+        then ok and refused
+
+    test step_descends_a_quadratic
+        given result = descend(500)
+        then @abs(result - 3.0) < 0.01
+
+    invariant adam_betas_are_below_one
+        assert DEFAULT_BETA1 < 1.0 and DEFAULT_BETA2 < 1.0 and DEFAULT_BETA1 < DEFAULT_BETA2 and DEFAULT_EPSILON > 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/an-encoder-block/card.png b/apps/website/public/ru/learn/an-encoder-block/card.png new file mode 100644 index 0000000000000000000000000000000000000000..0897ba76241e1153d636aa3c466b6d3bc0f73346 GIT binary patch literal 55439 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

+n9n_~Ltqv?tey@Oy0mH|KfJ+< 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 + + + + + +Блок энкодера: курс о нейросетях, урок 26 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Блок энкодера

+

Вы узнаете

Что один блок энкодера трансформера делает со своим входом и что меняет перенос нормализаций вперёд.

+

Слой трансформера это два подслоя, каждый обёрнут остаточным сложением и нормализацией слоя: самовнимание смешивает позиции, затем сеть прямого распространения ширины 8 работает с каждой позицией отдельно. В порядке post-norm из исходной статьи блок кончается нормализацией, поэтому у каждой строки выхода среднее 0 и дисперсия 1.000. Pre-norm ставит нормализации перед каждым подслоем и кончается остаточным сложением, поэтому его строки выходят с дисперсиями 2.73, 3.33 и 0.96; глубокие стопки так учатся легче, с одной нормализацией в самом верху. Спека encoder_block.t27 прогоняет один блок на 3 позициях, d_model 4 и 2 головах.

+

Попробовать

Переключайтесь между post-norm и pre-norm и читайте дисперсии строк; затем найдите позицию, которую голова 1 читает больше всего.

+

Открыть интерактивный урок →

+
An encoder block: what one transformer layer does
An encoder block: what one transformer layer does ↗
+

Three positions through one transformer block: attention, a residual, a feed-forward net and layer norm. Post-norm ends every row at mean 0 and variance 1; pre-norm does not.

+

specs/ml/transformer/encoder_block.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Standard Transformer encoder block with residual connections | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: attention and the FFN returned their input ("in real implementation
+// ..."), forward skipped both residuals, and the tests asked only for a non-empty
+// output from undeclared `default_input()`. The block now computes the Transformer
+// encoder layer over a seq x d_model input. Attention is multi-head scaled
+// dot-product, softmax(q k^T / sqrt(d_head)) v per head, with identity projections.
+// Then come the position-wise FFN and two residual + layer-norm steps: post-norm
+// LN(x + f(x)) by default, pre-norm x + f(LN(x)) when use_pre_norm is set.
+
+module EncoderBlock;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_D_MODEL : u32 = 512;
+    const DEFAULT_N_HEADS : u32 = 8;
+    const DEFAULT_D_FF : u32 = 2048;
+    const DEFAULT_DROPOUT : f32 = 0.1;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const EncoderBlockConfig = struct {
+        d_model : u32,
+        n_heads : u32,
+        d_ff : u32,
+        dropout : f32,
+        use_pre_norm : bool,
+    };
+
+    pub const FFNWeights = struct {
+        w1 : []const f32,
+        b1 : []const f32,
+        w2 : []const f32,
+        b2 : []const f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // q, k, v and out are seq x d_model; attn_weights is n_heads x seq x seq. Head h uses
+    // columns h * d_head .. (h + 1) * d_head.
+    fn multi_head_attention(query: []const f32, key: []const f32, value: []const f32, seq: usize, n_heads: u32, d_model: u32, out: []f32, attn_weights: []f32) -> void {
+        const d_head : usize = d_model / n_heads;
+        const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d_head)));
+        var h : usize = 0;
+        while (h < n_heads) {
+            var i : usize = 0;
+            while (i < seq) {
+                const row = attn_weights[(h * seq + i) * seq .. (h * seq + i + 1) * seq];
+                var max_s : f32 = -1.0e30;
+                var j : usize = 0;
+                while (j < seq) {
+                    var dot : f32 = 0.0;
+                    var c : usize = 0;
+                    while (c < d_head) {
+                        dot = dot + query[i * d_model + h * d_head + c] * key[j * d_model + h * d_head + c];
+                        c = c + 1;
+                    }
+                    row[j] = dot * scale;
+                    max_s = @max(max_s, row[j]);
+                    j = j + 1;
+                }
+                var sum : f32 = 0.0;
+                j = 0;
+                while (j < seq) {
+                    row[j] = exp(row[j] - max_s);
+                    sum = sum + row[j];
+                    j = j + 1;
+                }
+                var c : usize = 0;
+                while (c < d_head) {
+                    var acc : f32 = 0.0;
+                    j = 0;
+                    while (j < seq) {
+                        acc = acc + row[j] / sum * value[j * d_model + h * d_head + c];
+                        j = j + 1;
+                    }
+                    out[i * d_model + h * d_head + c] = acc;
+                    c = c + 1;
+                }
+                j = 0;
+                while (j < seq) {
+                    row[j] = row[j] / sum;
+                    j = j + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    // out = W2 relu(W1 x + b1) + b2 for one row; hidden is d_ff floats of scratch.
+    // Dropout is the identity at inference, which is what this block computes.
+    fn feed_forward(input: []const f32, weights: FFNWeights, d_model: u32, d_ff: u32, hidden: []f32, out: []f32) -> void {
+        var f : usize = 0;
+        while (f < d_ff) {
+            var z : f32 = weights.b1[f];
+            var j : usize = 0;
+            while (j < d_model) {
+                z = z + weights.w1[f * d_model + j] * input[j];
+                j = j + 1;
+            }
+            hidden[f] = @max(z, 0.0);
+            f = f + 1;
+        }
+        var o : usize = 0;
+        while (o < d_model) {
+            var y : f32 = weights.b2[o];
+            f = 0;
+            while (f < d_ff) {
+                y = y + weights.w2[o * d_ff + f] * hidden[f];
+                f = f + 1;
+            }
+            out[o] = y;
+            o = o + 1;
+        }
+    }
+
+    // (x - mean) / sqrt(var + 1e-5), no learned scale or shift
+    fn layer_norm(x: []const f32, out: []f32) -> void {
+        var mean : f32 = 0.0;
+        var k : usize = 0;
+        while (k < x.len) {
+            mean = mean + x[k];
+            k = k + 1;
+        }
+        mean = mean / @as(f32, @floatFromInt(x.len));
+        var variance : f32 = 0.0;
+        k = 0;
+        while (k < x.len) {
+            variance = variance + (x[k] - mean) * (x[k] - mean);
+            k = k + 1;
+        }
+        variance = variance / @as(f32, @floatFromInt(x.len));
+        k = 0;
+        while (k < x.len) {
+            out[k] = (x[k] - mean) / sqrt(variance + 0.00001);
+            k = k + 1;
+        }
+    }
+
+    // input and out are seq x d_model. scratch needs 3 seq d_model + n_heads seq^2 + d_ff + d_model floats.
+    fn forward(input: []const f32, seq: usize, ffn: FFNWeights, config: EncoderBlockConfig, out: []f32, scratch: []f32) -> void {
+        const n : usize = seq * config.d_model;
+        const d : usize = config.d_model;
+        const normed = scratch[0..n];
+        const attn = scratch[n .. 2 * n];
+        const mid = scratch[2 * n .. 3 * n];
+        const weights = scratch[3 * n .. 3 * n + config.n_heads * seq * seq];
+        const rest = 3 * n + config.n_heads * seq * seq;
+        const hidden = scratch[rest .. rest + config.d_ff];
+        const row = scratch[rest + config.d_ff .. rest + config.d_ff + d];
+        var t : usize = 0;
+        if (config.use_pre_norm) {
+            while (t < seq) {
+                layer_norm(input[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]);
+                t = t + 1;
+            }
+            multi_head_attention(normed, normed, normed, seq, config.n_heads, config.d_model, attn, weights);
+            var k : usize = 0;
+            while (k < n) {
+                mid[k] = input[k] + attn[k];
+                k = k + 1;
+            }
+            t = 0;
+            while (t < seq) {
+                layer_norm(mid[t * d .. (t + 1) * d], normed[t * d .. (t + 1) * d]);
+                feed_forward(normed[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row);
+                var c : usize = 0;
+                while (c < d) {
+                    out[t * d + c] = mid[t * d + c] + row[c];
+                    c = c + 1;
+                }
+                t = t + 1;
+            }
+            return;
+        }
+        multi_head_attention(input, input, input, seq, config.n_heads, config.d_model, attn, weights);
+        var k : usize = 0;
+        while (k < n) {
+            normed[k] = input[k] + attn[k];
+            k = k + 1;
+        }
+        t = 0;
+        while (t < seq) {
+            layer_norm(normed[t * d .. (t + 1) * d], mid[t * d .. (t + 1) * d]);
+            feed_forward(mid[t * d .. (t + 1) * d], ffn, config.d_model, config.d_ff, hidden, row);
+            var c : usize = 0;
+            while (c < d) {
+                normed[t * d + c] = mid[t * d + c] + row[c];
+                c = c + 1;
+            }
+            layer_norm(normed[t * d .. (t + 1) * d], out[t * d .. (t + 1) * d]);
+            t = t + 1;
+        }
+    }
+
+    // The fixture: seq 3, d_model 4, 2 heads, d_ff 8
+    fn cfg(pre_norm: bool) -> EncoderBlockConfig {
+        return EncoderBlockConfig{ .d_model = 4, .n_heads = 2, .d_ff = 8, .dropout = DEFAULT_DROPOUT, .use_pre_norm = pre_norm };
+    }
+
+    fn fixture_input(x: []f32) -> void {
+        const v : [12]f32 = [1.0, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 2.0, 1.0, 1.0, 0.0, 0.0];
+        var k : usize = 0;
+        while (k < 12) {
+            x[k] = v[k];
+            k = k + 1;
+        }
+    }
+
+    // which: 0 = out[index], 1 = attn_weights[index] of self-attention on the fixture
+    fn attention_at(which: u8, index: usize) -> f32 {
+        var x : [12]f32 = undefined;
+        fixture_input(&x);
+        var out : [12]f32 = [9.0] ** 12;
+        var weights : [18]f32 = [9.0] ** 18;
+        multi_head_attention(&x, &x, &x, 3, 2, 4, &out, &weights);
+        if (which == 0) {
+            return out[index];
+        }
+        return weights[index];
+    }
+
+    // Two keys equal: attention splits evenly and returns the mean of the values
+    fn tie_attention(index: usize) -> f32 {
+        const q : [2]f32 = [1.0, 1.0];
+        const k : [2]f32 = [2.0, 2.0];
+        const v : [2]f32 = [4.0, 10.0];
+        var out : [2]f32 = [0.0] ** 2;
+        var weights : [4]f32 = [0.0] ** 4;
+        multi_head_attention(&q, &k, &v, 2, 1, 1, &out, &weights);
+        return out[index];
+    }
+
+    fn ffn_fill(w1: []f32, b1: []f32, w2: []f32, b2: []f32) -> void {
+        var k : usize = 0;
+        while (k < 32) {
+            w1[k] = @as(f32, @floatFromInt((k * 5 + 1) % 9)) / 8.0 - 0.5;
+            w2[k] = @as(f32, @floatFromInt((k * 7 + 2) % 9)) / 8.0 - 0.5;
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 8) {
+            b1[k] = 0.1;
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 4) {
+            b2[k] = -0.1;
+            k = k + 1;
+        }
+    }
+
+    // which: 0 = out[index]; 1 = mean of row `index`; 2 = variance of row `index`
+    fn block_at(pre_norm: bool, which: u8, index: usize) -> f32 {
+        var x : [12]f32 = undefined;
+        fixture_input(&x);
+        var w1 : [32]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [32]f32 = undefined;
+        var b2 : [4]f32 = undefined;
+        ffn_fill(&w1, &b1, &w2, &b2);
+        var out : [12]f32 = [9.0] ** 12;
+        var scratch : [3 * 12 + 18 + 8 + 4]f32 = undefined;
+        forward(&x, 3, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, cfg(pre_norm), &out, &scratch);
+        if (which == 0) {
+            return out[index];
+        }
+        var mean : f32 = 0.0;
+        var c : usize = 0;
+        while (c < 4) {
+            mean = mean + out[index * 4 + c] / 4.0;
+            c = c + 1;
+        }
+        if (which == 1) {
+            return mean;
+        }
+        var variance : f32 = 0.0;
+        c = 0;
+        while (c < 4) {
+            variance = variance + (out[index * 4 + c] - mean) * (out[index * 4 + c] - mean) / 4.0;
+            c = c + 1;
+        }
+        return variance;
+    }
+
+    // FFN on row (1, 0, 0.5, -1) of the fixture weights; out[index]
+    fn ffn_at(index: usize) -> f32 {
+        var w1 : [32]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [32]f32 = undefined;
+        var b2 : [4]f32 = undefined;
+        ffn_fill(&w1, &b1, &w2, &b2);
+        const x : [4]f32 = [1.0, 0.0, 0.5, -1.0];
+        var hidden : [8]f32 = undefined;
+        var out : [4]f32 = [9.0] ** 4;
+        feed_forward(&x, FFNWeights{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, 4, 8, &hidden, &out);
+        return out[index];
+    }
+
+    fn valid_input() -> u32 {
+        return DEFAULT_D_MODEL / DEFAULT_N_HEADS;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Every attention row is a distribution; equal keys give the mean of the values
+    test multi_head_attention_basic_case
+        given row_sum = attention_at(1, 0) + attention_at(1, 1) + attention_at(1, 2)
+        when tied = tie_attention(0)
+        then @abs(row_sum - 1.0) < 0.000001 and tied == 7.0 and tie_attention(1) == 7.0 and attention_at(0, 0) != 9.0
+
+    // Heads are independent: head 1's weights (rows 9..17) differ from head 0's
+    test multi_head_attention_heads_differ
+        given w0 = attention_at(1, 1)
+        when w1 = attention_at(1, 10)
+        then w0 != w1 and w0 > 0.0 and w1 > 0.0
+
+    // W2 relu(W1 x + b1) + b2 on the fixture row, worked by hand: (0.4125, ..., -0.178125)
+    test feed_forward_basic_case
+        given y0 = ffn_at(0)
+        when y3 = ffn_at(3)
+        then @abs(y0 - 0.4125) < 0.000001 and @abs(y3 + 0.178125) < 0.000001 and @abs(ffn_at(2) + 0.928125) < 0.000001
+
+    // Post-norm: every output row has mean 0 and variance 1
+    test forward_basic_case
+        given mean1 = block_at(false, 1, 1)
+        when var1 = block_at(false, 2, 1)
+        then @abs(mean1) < 0.00001 and @abs(var1 - 1.0) < 0.001 and @abs(block_at(false, 1, 2)) < 0.00001
+
+    // Pre-norm keeps the residual stream un-normalised, so it differs from post-norm
+    test forward_pre_norm_differs
+        given pre = block_at(true, 0, 0)
+        when post = block_at(false, 0, 0)
+        then pre != post and pre == pre
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // d_model % n_heads == 0
+    invariant encoder_block_constraint_0
+        assert DEFAULT_D_MODEL % DEFAULT_N_HEADS == 0 and cfg(false).d_model % cfg(false).n_heads == 0
+
+    // d_ff >= d_model
+    invariant encoder_block_constraint_1
+        assert DEFAULT_D_FF >= DEFAULT_D_MODEL and cfg(false).d_ff >= cfg(false).d_model
+
+    // name: encoder_block -- each head gets d_model / n_heads columns
+    invariant encoder_block_constraint_2
+        assert valid_input() == 64
+
+    // "Vaswani et al. (2017) - Attention Is All You Need": dropout is a probability
+    invariant encoder_block_constraint_3
+        assert DEFAULT_DROPOUT >= 0.0 and DEFAULT_DROPOUT < 1.0
+
+    // "Baevski et al. (2020) - Revisiting the Self-Attention": both norm placements are offered
+    invariant encoder_block_constraint_4
+        assert cfg(true).use_pre_norm and !cfg(false).use_pre_norm
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/arithmetic-and-dsp/index.html b/apps/website/public/ru/learn/arithmetic-and-dsp/index.html index 258fbc0d1d..bb6ac26a68 100644 --- a/apps/website/public/ru/learn/arithmetic-and-dsp/index.html +++ b/apps/website/public/ru/learn/arithmetic-and-dsp/index.html @@ -63,7 +63,7 @@

Арифметика и DSP на FPGA: от цепи переноса до

Он продолжает курс о шинах. Каждый виджет в нём исполняет тела fn спеки t27, скомпилированные в WebAssembly: двигаете ползунок — отвечает спека.

Курс 9, 27 уроков, в каждом живой виджет и спека t27: сумматоры и цепи переноса, умножители и слайс DSP48E1, фиксированная точка, CORDIC, дискретизация, фильтры FIR и CIC, БПФ и фильтр на стенде. Каждое число считает скомпилированная спека.

Открыть интерактивный курс →

- +

Все уроки

diff --git a/apps/website/public/ru/learn/attention/card.png b/apps/website/public/ru/learn/attention/card.png new file mode 100644 index 0000000000000000000000000000000000000000..6606b8a8356b34e90726c3a0b8dcf41c5379a63f GIT binary patch literal 60475 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

awdFp*G5jCdA9gWMhq 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/attention/index.html b/apps/website/public/ru/learn/attention/index.html new file mode 100644 index 0000000000..9de3eed72f --- /dev/null +++ b/apps/website/public/ru/learn/attention/index.html @@ -0,0 +1,382 @@ + + + + + + +Внимание: курс о нейросетях, урок 24 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Внимание

+

Вы узнаете

Как внимание сравнивает каждый запрос с каждым ключом, что даёт softmax по каждой строке и что убирает причинная маска.

+

Внимание позволяет каждой позиции решить, какие другие позиции читать. Каждый запрос сравнивается с каждым ключом, q . k / sqrt(d), и softmax превращает каждую строку оценок в веса с суммой 1; выход это значения, усреднённые этими весами. Две головы делают это на двух половинах вектора. С причинной маской позиция не может читать будущее: в голове 0 позиция 0 читает только себя, позиция 1 делит 0.452 и 0.548, а позиция 2 распределяет 0.230, 0.321 и 0.449. Без маски каждая строка распределяется по всем трём ключам, от 0.21 до 0.47. Спека attention_mechanism.t27 вычисляет каждый вес на своей фикстуре.

+

Попробовать

Выключите и включите маску и прочитайте строку 0; затем сравните две головы в строке 2.

+

Открыть интерактивный урок →

+
Attention: how a word decides which other words to read
Attention: how a word decides which other words to read ↗
+

Two heads of attention over three positions: each row is how much one query reads each key. Switch on the causal mask and a position can no longer read the future.

+

specs/ml/recurrent/attention_mechanism.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Memory-efficient attention for long sequences | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: redeclared `var i` in one scope four times, called `@infinity()` and
+// `@random()` (not Zig), and indexed every row as head_dim wide inside d_model-wide
+// rows. backward also skipped the softmax Jacobian: it pushed dL/dweights straight
+// into the scores. It is now multi-head scaled dot-product attention over seq x
+// d_model rows. Head h reads columns h*hd .. (h+1)*hd, the weights are
+// heads x seq x seq, and causal masking is optional. backward is the exact
+// gradient, checked against finite differences. Dropout is carried in the config
+// and not applied: this is the inference computation.
+
+module Attention;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const NEG_INF : f32 = -1.0e30;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const AttentionConfig = struct {
+        d_model : u32,
+        num_heads : u32,
+        dropout : f32,
+        causal : bool,
+    };
+
+    pub const AttentionOutput = struct {
+        output : []f32,
+        weights : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn seq_of(query: []const f32, config: AttentionConfig) -> usize {
+        return query.len / config.d_model;
+    }
+
+    fn scale_of(config: AttentionConfig) -> f32 {
+        return 1.0 / sqrt(@as(f32, @floatFromInt(config.d_model / config.num_heads)));
+    }
+
+    fn forward(query: []const f32, key: []const f32, value: []const f32, output: []f32, weights: []f32, config: AttentionConfig) -> void {
+        const n = seq_of(query, config);
+        const d : usize = config.d_model;
+        const hd : usize = config.d_model / config.num_heads;
+        const scale = scale_of(config);
+        var h : usize = 0;
+        while (h < config.num_heads) {
+            var i : usize = 0;
+            while (i < n) {
+                const row = weights[(h * n + i) * n .. (h * n + i + 1) * n];
+                var max_s : f32 = NEG_INF;
+                var j : usize = 0;
+                while (j < n) {
+                    var score : f32 = NEG_INF;
+                    if (!(config.causal and j > i)) {
+                        score = 0.0;
+                        var k : usize = 0;
+                        while (k < hd) {
+                            score = score + query[i * d + h * hd + k] * key[j * d + h * hd + k];
+                            k = k + 1;
+                        }
+                        score = score * scale;
+                    }
+                    row[j] = score;
+                    max_s = @max(max_s, score);
+                    j = j + 1;
+                }
+                var sum : f32 = 0.0;
+                j = 0;
+                while (j < n) {
+                    row[j] = exp(row[j] - max_s);
+                    sum = sum + row[j];
+                    j = j + 1;
+                }
+                j = 0;
+                while (j < n) {
+                    row[j] = row[j] / sum;
+                    j = j + 1;
+                }
+                var k : usize = 0;
+                while (k < hd) {
+                    var acc : f32 = 0.0;
+                    j = 0;
+                    while (j < n) {
+                        acc = acc + row[j] * value[j * d + h * hd + k];
+                        j = j + 1;
+                    }
+                    output[i * d + h * hd + k] = acc;
+                    k = k + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    // dV_j += P_ij dO_i;  dP_ij = dO_i . V_j;  dS_ij = P_ij (dP_ij - sum_k P_ik dP_ik);
+    // dQ_i += scale dS_ij K_j;  dK_j += scale dS_ij Q_i  (per head; masked P_ij are 0)
+    fn backward(grad_output: []const f32, query: []const f32, key: []const f32, value: []const f32, attn_weights: []f32, grad_query: []f32, grad_key: []f32, grad_value: []f32, config: AttentionConfig) -> void {
+        const n = seq_of(query, config);
+        const d : usize = config.d_model;
+        const hd : usize = config.d_model / config.num_heads;
+        const scale = scale_of(config);
+        var x : usize = 0;
+        while (x < n * d) {
+            grad_query[x] = 0.0;
+            grad_key[x] = 0.0;
+            grad_value[x] = 0.0;
+            x = x + 1;
+        }
+        var h : usize = 0;
+        while (h < config.num_heads) {
+            var i : usize = 0;
+            while (i < n) {
+                const p = attn_weights[(h * n + i) * n .. (h * n + i + 1) * n];
+                var row_dot : f32 = 0.0;
+                var j : usize = 0;
+                while (j < n) {
+                    var dp : f32 = 0.0;
+                    var k : usize = 0;
+                    while (k < hd) {
+                        dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k];
+                        grad_value[j * d + h * hd + k] = grad_value[j * d + h * hd + k] + p[j] * grad_output[i * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    row_dot = row_dot + p[j] * dp;
+                    j = j + 1;
+                }
+                j = 0;
+                while (j < n) {
+                    var dp : f32 = 0.0;
+                    var k : usize = 0;
+                    while (k < hd) {
+                        dp = dp + grad_output[i * d + h * hd + k] * value[j * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    const ds = p[j] * (dp - row_dot) * scale;
+                    k = 0;
+                    while (k < hd) {
+                        grad_query[i * d + h * hd + k] = grad_query[i * d + h * hd + k] + ds * key[j * d + h * hd + k];
+                        grad_key[j * d + h * hd + k] = grad_key[j * d + h * hd + k] + ds * query[i * d + h * hd + k];
+                        k = k + 1;
+                    }
+                    j = j + 1;
+                }
+                i = i + 1;
+            }
+            h = h + 1;
+        }
+    }
+
+    fn cfg(causal: bool, dropout: f32) -> AttentionConfig {
+        return AttentionConfig{ .d_model = 4, .num_heads = 2, .dropout = dropout, .causal = causal };
+    }
+
+    // The fixture: seq 3, d_model 4, 2 heads (columns 0-1 and 2-3); q / k / v scaled down so the
+    // softmax is not saturated. which: 0 = output, 1 = weights.
+    fn fixture(q: []f32, k: []f32, v: []f32) -> void {
+        var x : usize = 0;
+        while (x < 12) {
+            q[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            k[x] = @as(f32, @floatFromInt(x / 4 + 1)) / 4.0 - @as(f32, @floatFromInt(x % 2)) / 3.0;
+            v[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            x = x + 1;
+        }
+    }
+
+    fn forward_at(causal: bool, which: u8, index: usize) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        var out : [12]f32 = [9.0] ** 12;
+        var w : [18]f32 = [9.0] ** 18;
+        forward(&q, &k, &v, &out, &w, cfg(causal, 0.0));
+        if (which == 0) {
+            return out[index];
+        }
+        return w[index];
+    }
+
+    // L = sum_x g_x O_x with g_x = (x + 1) / 10, one entry of q, k or v moved by delta
+    // (which: 0 = q, 1 = k, 2 = v)
+    fn loss(which: u8, index: usize, delta: f32) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        if (which == 0) {
+            q[index] = q[index] + delta;
+        }
+        if (which == 1) {
+            k[index] = k[index] + delta;
+        }
+        if (which == 2) {
+            v[index] = v[index] + delta;
+        }
+        var out : [12]f32 = undefined;
+        var w : [18]f32 = undefined;
+        forward(&q, &k, &v, &out, &w, cfg(false, 0.0));
+        var total : f32 = 0.0;
+        var x : usize = 0;
+        while (x < 12) {
+            total = total + @as(f32, @floatFromInt(x + 1)) / 10.0 * out[x];
+            x = x + 1;
+        }
+        return total;
+    }
+
+    fn grad(which: u8, index: usize, dropout: f32) -> f32 {
+        var q : [12]f32 = undefined;
+        var k : [12]f32 = undefined;
+        var v : [12]f32 = undefined;
+        fixture(&q, &k, &v);
+        var out : [12]f32 = undefined;
+        var w : [18]f32 = undefined;
+        forward(&q, &k, &v, &out, &w, cfg(false, dropout));
+        var g : [12]f32 = undefined;
+        var x : usize = 0;
+        while (x < 12) {
+            g[x] = @as(f32, @floatFromInt(x + 1)) / 10.0;
+            x = x + 1;
+        }
+        var gq : [12]f32 = undefined;
+        var gk : [12]f32 = undefined;
+        var gv : [12]f32 = undefined;
+        backward(&g, &q, &k, &v, &w, &gq, &gk, &gv, cfg(false, dropout));
+        if (which == 0) {
+            return gq[index];
+        }
+        if (which == 1) {
+            return gk[index];
+        }
+        return gv[index];
+    }
+
+    fn slope(which: u8, index: usize) -> f32 {
+        return (loss(which, index, 0.001) - loss(which, index, -0.001)) / 0.002;
+    }
+
+    fn valid_input() -> u32 {
+        return cfg(false, 0.0).d_model % cfg(false, 0.0).num_heads;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // Each weight row is a distribution, and each output is a weighted mean of the values
+    // (so it lies between the smallest and largest value in its column)
+    test forward_basic_case {
+        const row_sum = forward_at(false, 1, 0) + forward_at(false, 1, 1) + forward_at(false, 1, 2);
+        assert(@abs(row_sum - 1.0) < 0.000001);
+        assert(forward_at(false, 0, 0) + forward_at(false, 0, 1) + forward_at(false, 0, 2) + forward_at(false, 0, 3) > 0.0);  // computed a meaningful output
+        assert(forward_at(false, 0, 0) > 0.1 and forward_at(false, 0, 0) < 0.9);
+    }
+
+    // dQ, dK and dV against central differences of L = g . O
+    test backward_basic_case {
+        assert(@abs(grad(0, 0, 0.0) - slope(0, 0)) < 0.001);
+        assert(@abs(grad(0, 7, 0.0) - slope(0, 7)) < 0.001);
+        assert(@abs(grad(1, 5, 0.0) - slope(1, 5)) < 0.001);
+        assert(@abs(grad(2, 10, 0.0) - slope(2, 10)) < 0.001);
+        assert(grad(0, 0, 0.0) + grad(0, 1, 0.0) + grad(0, 2, 0.0) + grad(0, 3, 0.0) != 0.0);  // computed gradients
+    }
+
+    // Position 0 attends only to itself, position 1 to positions 0 and 1
+    test forward_causal_masking {
+        assert(forward_at(true, 1, 0) == 1.0);
+        assert(forward_at(true, 1, 1) == 0.0 and forward_at(true, 1, 2) == 0.0);
+        assert(forward_at(true, 1, 1 * 3 + 2) < 0.999);
+        assert(forward_at(true, 1, 1 * 3 + 2) == 0.0);
+        assert(forward_at(true, 0, 0) == 0.1);
+    }
+
+    // Dropout is not applied here (inference), so it leaves the gradients unchanged
+    test backward_dropout {
+        assert(grad(2, 3, 0.5) == grad(2, 3, 0.0));
+        assert(grad(0, 11, 0.5) == grad(0, 11, 0.0));
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // d_model % num_heads == 0
+    invariant attention_constraint_0
+        assert valid_input() == 0
+
+    // 0 <= dropout < 1
+    invariant attention_constraint_1
+        assert cfg(false, 0.5).dropout >= 0.0 and cfg(false, 0.5).dropout < 1.0
+
+    // query.shape == key.shape == value.shape: seq is read from the query
+    invariant attention_constraint_2
+        assert cfg(false, 0.0).d_model == 4
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/backpropagation/card.png b/apps/website/public/ru/learn/backpropagation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..c9986606c180749f91808fae6f262c4a7fce5a51 GIT binary patch literal 57570 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%0DFqoCcqiof!AvL4DkWv$yro{zAFqZVOvn!u9 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≺kew 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
15XA1UUKW{+VBk;#Pfczz5 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/backpropagation/index.html b/apps/website/public/ru/learn/backpropagation/index.html new file mode 100644 index 0000000000..075e842007 --- /dev/null +++ b/apps/website/public/ru/learn/backpropagation/index.html @@ -0,0 +1,289 @@ + + + + + + +Обратное распространение: курс о нейросетях, урок 19 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Обратное распространение

+

Вы узнаете

Как градиент каждого веса и каждого входа слоя следует из градиента его выходов.

+

Чтобы учиться, каждому весу нужно знать, как меняется потеря, когда он сдвигается. Обратное распространение отвечает по одному слою за раз: при данном g, насколько потеря хочет сдвинуть каждый выход, вес от входа i к выходу o получает g_o x_i, а вход i получает сумму по o от W[o][i] g_o и передаёт её слою ниже. При входах (1, 2, 3) и g = (1, 0.5) градиенты весов равны 1, 2, 3 и 0.5, 1, 1.5, а градиенты входов 0.5, 2 и 3.5. Слой линейный, поэтому сдвиг x0 на 1 сдвигает потерю g . y с 15.25 до 15.75, на его градиент 0.5. Спека dense_layer.t27 вычисляет все три.

+

Попробовать

Поставьте g = (1, 0) и посмотрите, какие рёбра гаснут; затем поставьте g = (-2, 1) и проверьте градиенты входов вручную.

+

Открыть интерактивный урок →

+
Backpropagation: how blame flows back through a layer
Backpropagation: how blame flows back through a layer ↗
+

Set how much the loss wants each of two outputs to move: every weight gets that times its input, every input gets W transposed times it. The edges and nodes show the numbers.

+

specs/ml/layers/dense_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Row-major weight layout for cache efficiency | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward and backward were empty placeholders, the tests asserted
+// `result != undefined`, and the invariants asserted `true` over an undeclared
+// `valid_input`. Dense is now y = act(W x + b) with W row-major
+// (output_size x input_size), and backward gives the three gradients.
+
+module Dense;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const MIN_INPUT_SIZE : u32 = 1;
+    const MAX_INPUT_SIZE : u32 = 4096;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const DenseConfig = struct {
+        input_size : u32,
+        output_size : u32,
+        has_bias : bool,
+        activation : ActivationType,
+    };
+
+    pub const ActivationType = enum(u8) {
+        None,
+        ReLU,
+        GELU,
+        Sigmoid,
+        Tanh,
+        Softmax,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // relu, the one activation the tests exercise besides None
+    fn activate(z: f32, activation: ActivationType) -> f32 {
+        if (activation == ActivationType.ReLU) {
+            if (z > 0.0) {
+                return z;
+            }
+            return 0.0;
+        }
+        return z;
+    }
+
+    // output[o] = act(sum_i weights[o * in + i] * input[i] + bias[o])
+    fn forward(input: []const f32, weights: []const f32, bias: []const f32, config: DenseConfig, output: []f32) -> void {
+        var o : usize = 0;
+        while (o < config.output_size) {
+            var z : f32 = 0.0;
+            if (config.has_bias) {
+                z = bias[o];
+            }
+            var i : usize = 0;
+            while (i < config.input_size) {
+                z = z + weights[o * config.input_size + i] * input[i];
+                i = i + 1;
+            }
+            output[o] = activate(z, config.activation);
+            o = o + 1;
+        }
+    }
+
+    // For a linear layer (activation None), given dL/dy = grad_output:
+    //   grad_input[i] = sum_o W[o][i] grad_output[o]       (W^T g)
+    //   grad_weights[o][i] = grad_output[o] * input[i]      (g x^T)
+    //   grad_bias[o] = grad_output[o]
+    fn backward(grad_output: []const f32, input: []const f32, weights: []const f32, config: DenseConfig, grad_input: []f32, grad_weights: []f32, grad_bias: []f32) -> void {
+        var i : usize = 0;
+        while (i < config.input_size) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var o : usize = 0;
+        while (o < config.output_size) {
+            grad_bias[o] = grad_output[o];
+            i = 0;
+            while (i < config.input_size) {
+                grad_input[i] = grad_input[i] + weights[o * config.input_size + i] * grad_output[o];
+                grad_weights[o * config.input_size + i] = grad_output[o] * input[i];
+                i = i + 1;
+            }
+            o = o + 1;
+        }
+    }
+
+    // The fixture: 3 inputs, 2 outputs, W = [[1, 2, 3], [-1, 0, 1]], b = [0.5, -0.5]
+    fn cfg(activation: ActivationType) -> DenseConfig {
+        return DenseConfig{ .input_size = 3, .output_size = 2, .has_bias = true, .activation = activation };
+    }
+
+    fn forward_at(x0: f32, x1: f32, x2: f32, activation: ActivationType, index: usize) -> f32 {
+        const input : [3]f32 = [x0, x1, x2];
+        const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0];
+        const bias : [2]f32 = [0.5, -0.5];
+        var output : [2]f32 = [0.0] ** 2;
+        forward(&input, &weights, &bias, cfg(activation), &output);
+        return output[index];
+    }
+
+    // L = g . y for g = (g0, g1): the loss whose gradients backward computes
+    fn loss_at(x0: f32, x1: f32, x2: f32, g0: f32, g1: f32) -> f32 {
+        return g0 * forward_at(x0, x1, x2, ActivationType.None, 0) + g1 * forward_at(x0, x1, x2, ActivationType.None, 1);
+    }
+
+    // which: 0 = grad_input, 1 = grad_weights, 2 = grad_bias
+    fn backward_at(g0: f32, g1: f32, which: u8, index: usize) -> f32 {
+        const grad_output : [2]f32 = [g0, g1];
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const weights : [6]f32 = [1.0, 2.0, 3.0, -1.0, 0.0, 1.0];
+        var grad_input : [3]f32 = [9.0] ** 3;
+        var grad_weights : [6]f32 = [9.0] ** 6;
+        var grad_bias : [2]f32 = [9.0] ** 2;
+        backward(&grad_output, &input, &weights, cfg(ActivationType.None), &grad_input, &grad_weights, &grad_bias);
+        if (which == 0) {
+            return grad_input[index];
+        }
+        if (which == 1) {
+            return grad_weights[index];
+        }
+        return grad_bias[index];
+    }
+
+    // An empty layer (no inputs, no outputs) writes nothing
+    fn empty_forward_untouched() -> bool {
+        const none : [0]f32 = [];
+        var sentinel : [1]f32 = [7.0];
+        const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None };
+        forward(&none, &none, &none, empty_cfg, &sentinel);
+        return sentinel[0] == 7.0;
+    }
+
+    fn empty_backward_untouched() -> bool {
+        const none : [0]f32 = [];
+        var sentinel : [1]f32 = [7.0];
+        const empty_cfg = DenseConfig{ .input_size = 0, .output_size = 0, .has_bias = true, .activation = ActivationType.None };
+        backward(&none, &none, &none, empty_cfg, &sentinel, &sentinel, &sentinel);
+        return sentinel[0] == 7.0;
+    }
+
+    fn valid_input() -> f32 {
+        return forward_at(1.0, 2.0, 3.0, ActivationType.None, 0);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // x = (1, 2, 3): y0 = 1 + 4 + 9 + 0.5 = 14.5, y1 = -1 + 0 + 3 - 0.5 = 1.5
+    test forward_basic_case
+        given y0 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 0)
+        when y1 = forward_at(1.0, 2.0, 3.0, ActivationType.None, 1)
+        then y0 == 14.5 and y1 == 1.5
+
+    // ReLU clips the negative pre-activation: x = (0, 0, -1) gives y = (-2.5, -1.5) -> (0, 0)
+    test forward_relu_clips_negatives
+        given linear = forward_at(0.0, 0.0, -1.0, ActivationType.None, 0)
+        when clipped = forward_at(0.0, 0.0, -1.0, ActivationType.ReLU, 0)
+        then linear == -2.5 and clipped == 0.0 and forward_at(1.0, 2.0, 3.0, ActivationType.ReLU, 0) == 14.5
+
+    test forward_empty_input
+        given result = empty_forward_untouched()
+        then result
+
+    // g = (1, 2): grad_input = W^T g = (1 - 2, 2 + 0, 3 + 2) = (-1, 2, 5); grad_bias = g;
+    // grad_weights[1][2] = g1 * x2 = 6
+    test backward_basic_case
+        given gi0 = backward_at(1.0, 2.0, 0, 0)
+        when gi2 = backward_at(1.0, 2.0, 0, 2)
+        then gi0 == -1.0 and backward_at(1.0, 2.0, 0, 1) == 2.0 and gi2 == 5.0 and backward_at(1.0, 2.0, 2, 1) == 2.0 and backward_at(1.0, 2.0, 1, 5) == 6.0
+
+    // dL/dx1 by finite difference equals grad_input[1]
+    test backward_matches_finite_difference
+        given slope = (loss_at(1.0, 2.0 + 0.01, 3.0, 1.0, 2.0) - loss_at(1.0, 2.0 - 0.01, 3.0, 1.0, 2.0)) / 0.02
+        when result = backward_at(1.0, 2.0, 0, 1)
+        then @abs(result - slope) < 0.001
+
+    test backward_empty_gradient
+        given result = empty_backward_untouched()
+        then result
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.size() == config.input_size: the bounds the layer accepts
+    invariant dense_constraint_0
+        assert MIN_INPUT_SIZE >= 1 and MAX_INPUT_SIZE >= MIN_INPUT_SIZE
+
+    // output.size() == config.output_size: each output is one row of W x + b
+    invariant dense_constraint_1
+        assert valid_input() == 14.5
+
+    // weights.size() == input_size * output_size: the fixture holds 3 * 2 = 6 weights
+    invariant dense_constraint_2
+        assert cfg(ActivationType.None).input_size * cfg(ActivationType.None).output_size == 6
+
+    // bias.size() == output_size (if has_bias): the fixture carries a bias of 2
+    invariant dense_constraint_3
+        assert cfg(ActivationType.None).has_bias
+
+    // All inputs must be finite (no NaN/Inf): finite in, finite out
+    invariant dense_constraint_4
+        assert valid_input() == valid_input()
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/batch-normalisation/card.png b/apps/website/public/ru/learn/batch-normalisation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..6aec1075204563c103c76fa2ae60ed9ae71a42b9 GIT binary patch literal 59224 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

3s*k7@<)8K|ylz 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 Ut)~3D-{YB`wWHPVzxe$2cTWE~!T + + + + + +Пакетная нормализация: курс о нейросетях, урок 12 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Пакетная нормализация

+

Вы узнаете

Как пакетная нормализация приводит признаки разного масштаба к одному и чем она пользуется при выводе.

+

Признаки разного масштаба дёргают сеть: в пакете спеки один признак в десять раз больше другого. Пакетная нормализация вычитает среднее каждого признака по пакету и делит на его разброс, поэтому признаки 1, 2, 3, 4 и 10, 20, 30, 40 оба выходят как -1.34, -0.45, 0.45 и 1.34, а -1, -1, 1, 1 выходит как -1 и 1. Затем выученные gamma и beta масштабируют и сдвигают его обратно, где это полезно. При выводе слой вместо пакета использует скользящие средние: при среднем 0, дисперсии 1, gamma 1 и beta 0.25 входы 1, 2 и 3 дают 1.25, 2.25 и 3.25. Спека batchnorm_layer.t27 вычисляет оба режима.

+

Попробовать

Сравните два нормализованных столбца; затем поставьте скользящее среднее 2 и дисперсию 4 и прочитайте выходы вывода.

+

Открыть интерактивный урок →

+
Batch norm: features on very different scales, made comparable
Batch norm: features on very different scales, made comparable ↗
+

A batch of 4 samples whose 3 features live on scales 1, 10 and 1: batch norm gives each feature mean 0 and variance 1. Then set gamma and the running statistics for inference.

+

specs/ml/layers/batchnorm_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Prevent division by zero in sqrt | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward copied one element and backward zeroed two gradients
+// (placeholders), and the tests pinned those placeholders: output[0] == input[0],
+// grad_gamma[0] == grad_beta[0] == 0. They now compute batch normalisation:
+// forward/backward in inference form, normalising by the running statistics, and
+// forward_train normalising by the batch's own mean and variance.
+
+module Batchnorm;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_EPSILON : f32 = 1.0e-5;
+    const DEFAULT_MOMENTUM : f32 = 0.1;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const BatchNormConfig = struct {
+        num_features : u32,
+        epsilon : f32,
+        momentum : f32,
+        affine : bool,
+        track_running_stats : bool,
+    };
+
+    pub const BatchNormState = struct {
+        running_mean : []f32,
+        running_var : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Inference: output[f] = gamma[f] (input[f] - running_mean[f]) / sqrt(running_var[f] + eps) + beta[f]
+    fn forward(input: []const f32, gamma: []const f32, beta: []const f32, state: BatchNormState, output: []f32, config: BatchNormConfig) -> void {
+        var f : usize = 0;
+        while (f < config.num_features) {
+            const x_hat = (input[f] - state.running_mean[f]) / sqrt(state.running_var[f] + config.epsilon);
+            output[f] = gamma[f] * x_hat + beta[f];
+            f = f + 1;
+        }
+    }
+
+    // Inference backward (mean and variance are constants here):
+    //   grad_input[f] = grad_output[f] gamma[f] / sqrt(var[f] + eps)
+    //   grad_gamma[f] = grad_output[f] x_hat[f],  grad_beta[f] = grad_output[f]
+    fn backward(grad_output: []const f32, input: []const f32, gamma: []const f32, beta: []const f32, mean: []const f32, var: []const f32, grad_gamma: []f32, grad_beta: []f32, grad_input: []f32, config: BatchNormConfig) -> void {
+        var f : usize = 0;
+        while (f < config.num_features) {
+            const inv_std = 1.0 / sqrt(var[f] + config.epsilon);
+            grad_gamma[f] = grad_output[f] * (input[f] - mean[f]) * inv_std;
+            grad_beta[f] = grad_output[f];
+            grad_input[f] = grad_output[f] * gamma[f] * inv_std;
+            f = f + 1;
+        }
+    }
+
+    // Training: input is batch x num_features, row-major. Each feature is normalised by
+    // its own batch mean and (biased) batch variance, then scaled and shifted.
+    fn forward_train(input: []const f32, batch: usize, gamma: []const f32, beta: []const f32, output: []f32, config: BatchNormConfig) -> void {
+        const nf : usize = config.num_features;
+        var f : usize = 0;
+        while (f < nf) {
+            var mean : f32 = 0.0;
+            var b : usize = 0;
+            while (b < batch) {
+                mean = mean + input[b * nf + f];
+                b = b + 1;
+            }
+            mean = mean / @as(f32, @floatFromInt(batch));
+            var variance : f32 = 0.0;
+            b = 0;
+            while (b < batch) {
+                const d = input[b * nf + f] - mean;
+                variance = variance + d * d;
+                b = b + 1;
+            }
+            variance = variance / @as(f32, @floatFromInt(batch));
+            b = 0;
+            while (b < batch) {
+                output[b * nf + f] = gamma[f] * (input[b * nf + f] - mean) / sqrt(variance + config.epsilon) + beta[f];
+                b = b + 1;
+            }
+            f = f + 1;
+        }
+    }
+
+    fn cfg() -> BatchNormConfig {
+        return BatchNormConfig{ .num_features = 3, .epsilon = DEFAULT_EPSILON, .momentum = DEFAULT_MOMENTUM, .affine = true, .track_running_stats = true };
+    }
+
+    // forward on input (1, 2, 3), gamma g, beta 0.25, running mean 0 / var 1 (or mean 2 / var 4)
+    fn forward_at(g: f32, shifted: bool, index: usize) -> f32 {
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const gamma : [3]f32 = [g, g, g];
+        const beta : [3]f32 = [0.25, 0.25, 0.25];
+        var mean : [3]f32 = [0.0, 0.0, 0.0];
+        var variance : [3]f32 = [1.0, 1.0, 1.0];
+        if (shifted) {
+            mean = [2.0, 2.0, 2.0];
+            variance = [4.0, 4.0, 4.0];
+        }
+        const state = BatchNormState{ .running_mean = &mean, .running_var = &variance };
+        var output : [3]f32 = [0.0] ** 3;
+        forward(&input, &gamma, &beta, state, &output, cfg());
+        return output[index];
+    }
+
+    // which: 0 = grad_gamma, 1 = grad_beta, 2 = grad_input; grad_output 1, gamma 2, mean 0, var 1
+    fn backward_at(which: u8, index: usize) -> f32 {
+        const grad_output : [3]f32 = [1.0, 1.0, 1.0];
+        const input : [3]f32 = [1.0, 2.0, 3.0];
+        const gamma : [3]f32 = [2.0, 2.0, 2.0];
+        const beta : [3]f32 = [0.0, 0.0, 0.0];
+        const mean : [3]f32 = [0.0, 0.0, 0.0];
+        const variance : [3]f32 = [1.0, 1.0, 1.0];
+        var grad_gamma : [3]f32 = [9.0] ** 3;
+        var grad_beta : [3]f32 = [9.0] ** 3;
+        var grad_input : [3]f32 = [9.0] ** 3;
+        backward(&grad_output, &input, &gamma, &beta, &mean, &variance, &grad_gamma, &grad_beta, &grad_input, cfg());
+        if (which == 0) {
+            return grad_gamma[index];
+        }
+        if (which == 1) {
+            return grad_beta[index];
+        }
+        return grad_input[index];
+    }
+
+    // forward_train on a batch of 4 samples x 3 features; returns output[b][f]
+    fn train_at(b: usize, f: usize) -> f32 {
+        const input : [12]f32 = [1.0, 10.0, -1.0, 2.0, 20.0, -1.0, 3.0, 30.0, 1.0, 4.0, 40.0, 1.0];
+        const gamma : [3]f32 = [1.0, 1.0, 1.0];
+        const beta : [3]f32 = [0.0, 0.0, 0.0];
+        var output : [12]f32 = [0.0] ** 12;
+        forward_train(&input, 4, &gamma, &beta, &output, cfg());
+        return output[b * 3 + f];
+    }
+
+    fn valid_input() -> u32 {
+        return cfg().num_features;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // With mean 0, var 1, gamma 1, beta 0 the layer is the identity up to eps:
+    // 1 / sqrt(1 + 1e-5) = 0.999995 (the old `==` held only for the copy placeholder)
+    test "forward_basic_case"
+        given out0 = forward_at(1.0, false, 0) - 0.25
+        when out2 = forward_at(1.0, false, 2) - 0.25
+        then @abs(out0 - 1.0) < 0.00001 and @abs(out2 - 3.0) < 0.00003
+
+    // mean 2, var 4: (x - 2) / 2 * gamma + beta, so x = 3 with gamma 2 gives 1.25
+    test "forward_uses_running_statistics"
+        given result = forward_at(2.0, true, 2)
+        when centre = forward_at(2.0, true, 1)
+        then @abs(result - 1.25) < 0.00001 and centre == 0.25
+
+    // grad_gamma = g x_hat = (1, 2, 3) / sqrt(1 + eps), grad_beta = g = 1,
+    // grad_input = g gamma / sqrt(1 + eps) = 2 (the old 0, 0 were the placeholder's)
+    test "backward_basic_case"
+        given grad_gamma = backward_at(0, 2)
+        when grad_input = backward_at(2, 0)
+        then @abs(grad_gamma - 3.0) < 0.0001 and backward_at(1, 0) == 1.0 and grad_input != 0.0 and @abs(grad_input - 2.0) < 0.0001
+
+    // Each feature of the batch comes out with mean 0 and variance 1
+    test "forward_train_normalises_each_feature"
+        given mean_f1 = train_at(0, 1) + train_at(1, 1) + train_at(2, 1) + train_at(3, 1)
+        when var_f1 = (train_at(0, 1) * train_at(0, 1) + train_at(1, 1) * train_at(1, 1) + train_at(2, 1) * train_at(2, 1) + train_at(3, 1) * train_at(3, 1)) / 4.0
+        then @abs(mean_f1) < 0.00001 and @abs(var_f1 - 1.0) < 0.0001 and @abs(train_at(0, 0) - train_at(0, 1)) < 0.00001 and @abs(train_at(0, 2) + 1.0) < 0.0001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // num_features > 0
+    invariant batchnorm_constraint_0
+        assert valid_input() > 0
+
+    // epsilon > 0
+    invariant batchnorm_constraint_1
+        assert DEFAULT_EPSILON > 0.0
+
+    // 0 <= momentum < 1
+    invariant batchnorm_constraint_2
+        assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0
+
+    // gamma.size() == num_features: the fixtures carry 3 of each
+    invariant batchnorm_constraint_3
+        assert valid_input() == 3
+
+    // beta.size() == num_features: beta shifts every feature, so x = mean gives exactly beta
+    invariant batchnorm_constraint_4
+        assert forward_at(2.0, true, 1) == 0.25
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/capstone-a-filter-on-the-board/index.html b/apps/website/public/ru/learn/capstone-a-filter-on-the-board/index.html index d252d6b837..e05cb94460 100644 --- a/apps/website/public/ru/learn/capstone-a-filter-on-the-board/index.html +++ b/apps/website/public/ru/learn/capstone-a-filter-on-the-board/index.html @@ -1118,7 +1118,7 @@

Итог: фильтр на плате

} // phi^2 + 1/phi^2 = 3 | TRINITY

Открыть спеку урока в плеере ↗

- +

Все уроки

diff --git a/apps/website/public/ru/learn/cross-entropy/card.png b/apps/website/public/ru/learn/cross-entropy/card.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6845c3005cce9e7340336cdb478c5dd3b96103 GIT binary patch literal 59257 zcmeFYRZv{r*X{izgy0?=8g~!w!QEXG+}%C62X}XOhb9D<;O+!>_r}i7^Zws+`Bk0z z>eMH7`hp9(>F&MPnsbctn~QKoc?l$VJotb9`3Ff#QdIe$e?HXy^Ur%%*!RG1evzIa z{PPd$KT@JXs_vO5Ybd&(TwVn)6h__$3_)P}t3F`9uM3JtA4OF`pbM`T)GSe+mvZw+ zyOldxAo?wRIs&dls9~FxuBV@Yr+p(%Q#5!-k(=*77m)v+H0%q+YYefH?gY8x8N>DK z#PKFWM?*sgYePfM!an~sE{u@qzYo`8Ayl-#k2pO;Vsg^Ik9rlvp#MA>;U63J_c0{T zf{Om{%a&+93jg~mQr`YAlK;NUxC93_{NIw{?25TvsJw)QweZ7mrEF6wYRNG8w)2MG z=BN&%E0V=YV?(#bAgi?u0mEtCyasVdJH`qMo{L zY#Kq=H=*YrJu{~3NeK(lbq-GXy}M&y5;6C8i%Q4`n0~yCoUj6=can5%;x^_%+!}-0 z6r7P+57*CoXT- zn$JODnFh{h5BU=pAK6ZKu>syU{jM4a*n;RsXSH9!J!xmwufsRD^IiTQX5i}qh|hj! zM4-gbD0d6W99vdLxZ4@C`Bi3U&GFZ`Hb@i7U8-k8)fV4QGk0BHvB2S_-FAwNfF=VE zXXv^}K<{7_!BNrixq4`lCo`*$7bH7=z;4ChPpTG*glCfP(*S-33Y^E21MkIfebQl( zEt%P9+e%IKly+6lPY5{pjG6g)Gt_R{B529Q=87R3a{J;}GyGZKN%H_@FyzjzodyX$ zhx?kc288J)=wasKsic>n#f_5w%-js^q|?e!I|!ebuo2a_6GVL;($%yswE4h9I>gF% zB&dZ=4$tKg`oUvi;|>Mx(i!q|6`3?#=YEcZs(9r78l<3l{)q}dB!^0g& zq}v(k7_qb!-eRf!{Nmyt)C@}G=7B=NP8a7~t#R{|^7#!e(a257ShDca=b*WJSH{3# zsi39`%egj5{JdWh8KWV^--Ib4t-$`gIoaVygn?TPQJe?8xV*Tue-VtiiFc}cSQmi` zB_$!)$Z#04j;i4D-BEqPAXtUmACmCsYuJA0y+H4feEcl-PPJ-OLvl;u;zna z2Vu~yTe6{4)BMbmAm0$HZ%rBL++ojL%dI}cS~*ivIM`&9B<747TMtFL<1$>Co@o&W zgMGi@TJY=;yc2X&A8Y>xOWsq12cL86QOm{6Qncs{qL++<>r#M=mDe}g@1ruL5Tn;8 zNO1J!R~pG@xpc&%mx+nVYWTK&uZ-t{$4qP5O>qACuWp*E5|r7`BM~jf!p6abwrBA; zuI6=xd!}6H9^1xG|B18P2;ZPjIrc>EI^M+XZa*d+H0g|U9&(QCG@J;%Bx3t?KRQ2s zbd!b~Y(&}#4v2$|Jkq&R-jyB+l(;iK9BZ1iMDcET&rbUYr+j-jmEoMfZBZCC(-<)a zeM9is0ezYneKsPACbYaLSl}u<^!%syLE+G!PP!SHWe#*w6y)=bQ8viUoE>=+d4%+o z>%gh6Z4;z%u3~q>(2_KULoI-RH)nq`n5OzV6^(kg`#kMYTI!*KpT9Q$aFCm$Ugi2K43Ml?HM${p zhK3+Y2-FNoTWAir6lrZ(GgV^Z@oh~F6cuNS1inDRwjpFq`Bgwm74RrlJ>bi3^S#~k z*)wbtInVRuDN8Z*YS#}F5Q&8iK0So^Pil{k&p~^5qz&V%T#Xavhj|sY$2QD2Og(y( z{Qk^2AcKC5C`Ln7bAi*=mzq7v;W4=;$k(UyqYgizNc0%@)6O}$b;?sIcX+r{KxV}Z zwnYE);LTxt34#iGLfnr|C9<1%tdN9H3rT#bwg!g0dYNhATCi0mEq7q18V$)8_$Y;; zlZZJrQqp{c;=7@B+0HM~lVd_7fxV$T8U(9O2Z`Y{gb)~k;m~zolF|)K(^CeUW9VHzrIAxHIF1A_?3W>wj5 zlOiZ%Uu{xXhj~dUdsMg+7-|^CZ=9}>#IsIu#{VMiAGn<9YBfif7WYP{0?#u%krn|?Ga=Wv=?u-?E-T6^N#7I zO^ugK6g{1(8gHBa%A}&+umt4M{P9hLvY-=hGimN)arx}W2PdYk=c`DCi8PQvVadTN z(4lXV)pZWvc~EeaR!kB}ur0KD+}QS-oJ@Lgy?-qWJaohsUYWYVVcT2B-3GIjjOK7H z{<4|0pUqS_yeFWYI_GyLz|Yu-U2o?65c#48D`$@q5rMQIZH8IQmV=u4Twquj9$5sQ zru3+NMV$&5y#WV+Z)6XNC04g-7;&g->KfJ|&R)|U*S5D-E4oJ~xJ~pd`gj-|OadHd zthZ!>C?!LaVv*~EZU@EH&>_QsaAti;vB6|QF9A& zJ`ZA}npH^&Qc(~A&2G0y$9*cpgL85+I8fY|&Q>4eyz_~t>s8ryzV(o?i{{RMSY)~O zb%&4Hewv@vY#npmHPrF$!hS}QYE~_$Yy6m&wvf~zX5B`U#Q6dT#HXrK$NBOt*jxk| zM0TEzcDNui3zF3CYDg1_oZ9sdC{^C67N_mwy~Giiy+bFd5usj{=x6+a5Qn}rU=lu- z{Jbh+n7IE(RQ@X zCdu+v?!lam8`?*+w=nzNWIt8wzWN&!H8Z{Jv{n{YN=9lv9#UPp-R`3s(cj3^E_i>i z(a|tki05@A#rlJ;BO>Ir%{;#9=&9?Cy$6hRT+@;CooTWx0rqF{8;6ABz$X1-N~hRs zJsX?tDbVpzp=ZoMcbf&BDtGL3L@$&AXk^igoU5_x>&0XxnLkf7S8%=o>mc^LmXfU_ zLi(j_tYgESs@P#1)S;BrA&idSKLvqTOKYprtO8muV>LycFO=fzpvswpfI*}U4|BH+ z0+K^!=AARIK`FAm+)}m9O1S|q2m9C!kF_$DeWFus4XPS;7^GLK<-ISO9_~sGd<-vN z#HwTljTK5OUwHT{t2>l^ae<+Q z?8;Re6@r*MW^9G=W3^B4o8R%V`a8c0-DNeDk;;XnEm6DvF^IKw3 za2Ny_!xB1xjayr+nVb=Iw69uEnqZD(iMAg-QnH>=j1Yj`6=)z)r6nyj2k${zKDJDMh-| zZaZjPukz#0qzXv?MsnWP$ECsQc=j?RY3IAk4z}~!8j2vFPvK+vK^fGBZ(8_BJ==2C z@}l@SPZx<#EDXvCKdBu%X6PNLEQzt>^N`#k)>AcVdrW#tEHl**u9A_KY~>+>JPs=& zRl-u~!K~vnT+sCG0m5e$_`*t+tdwjm`e*(ZkpRA|dd4B>X#|yIio(#rVDpM=^b{NG zm4*{|bfbJD&SWuj5sm@KAiaJq3%~m5uPH|wcP3c4`;=rQE$N{+o?z{m#eSUZJ%~T%mTBmY5Zc9An5YrO;Pj-|6q=p?8E9I10Cu-RPS|BBUp6 zE5(cw=7au|{EB#MqIe)mCK5{8@qkDqHbg3wthCfc^#T=7h{VuBYOJLWi}<}v37VzG z*HnZ;qIDL*#(VE6{UQ>tFfgA1|LJs_qLIm{U#9#@@!P#P} zLbeq7=xUMD{Pr(A9+N6`IntWcz@8qGb_s3ndK=JhSti?Kdebk-)CgIgebn%EJ0L-k zA?07D=Do2`7+2tRIZ9N^d%wx{GTFBhYPs`!ib&C-*y;!&mLZCMPOO8oY5~dfq5YLw z-=nak@m6f{*m5^lo2Y8pFhuN-4!by#!=?O2wTg{irXYe0J>T1)KO%xdiyFD}B_OnY z4g@icY2t1^Ggg}C+(7K|7LQ%YC3(qekmm^Z#DsKSN!55IaJ=x`tp9c~q6{^zmZh=8 zgCpb%8Nx1f!x!MbyOg?hyE|Z5+ukiXPHUP7LC@<1eLmXZB=arcYnSR4pRE*VEc~>< zoQW7eJOJh>r)zuq4W*w>tXHwFw^%w8JRFHlPMY*M$f%Dh@Wo~%;Kuk6FD{>pf~6?B zJZZQ8&|~^rwGdh}Zz>%cn$lA_Be(O#x47lae9R(>EBpMHC;SB<06a;;tR@}Ba9RfP zcHAcC7tH15S2x<%=(jr<*BtG_6d70tsrvKHZA~ic<<-Pq#X6mXY`&_L5h<7S`!|uz zsu9F7aUT}*o^K%_+k#%|l&xeUm&s9iZa@N#k})b?GxyD<)mnN=v@!PE#XLQ7dWYGC zO!wL7cs1cIFeq#e0#@gFz5F{m{E!K)eP0+)LIS&N*fpzwh#M=3##79$_R2Pp$NDC`Pcn%&^m_$evKFN|R@X~qi!=(44v zJ+1g-62epyxu_n9^U;^XHm?8J7yTBf z`_H3k&S!`mq3b*-kJ}omv#wjBntJsbF^#(%&aG#w{+Y-iX;<1MokgtPO|E+s_^WBv z6E*&4jnhZz3E_s}_Gj~(mc~}$*3o?>pBB81YYlWW5&gU`F^7h0B z33zdNEN$(4Chy_CjI?8qvfgIbxG*{MWGX^u8EW!H7qP#4(@H zKYQd8X&*x>*P?qfoZd)$*c|<9m(vyfEvH2-k}l|&PhmGHu#l1y)a?!KDi!=pvj;Vo^$^Y#c`kM z`{H3w7`mPk9iF)E#Q?HMV8vvAak1Tcs5ykuZY0ixfeuBHKoJ$o^Y*PMZ_mGxo7NOa z&%+=KoFEDsuo*H@9uyny7O#NpkZ_~j6Y;DjGYS~^?W1xeW){9z(v@~t^*~83>I)IA zWM*lNV#|#3mg7Cd`-qk4x>tG2$EjM<;G71f(xxJyq{vgkKvDCsYDJ1>x)**yd2ekPkzSSkpvR(N$DbKc&x7DaACwSNQ;7 z>L&jqk&VhXWzOs3JfRjr0_UePmHbd|9)tdM1%XxHq1Loh!02RqQGI2^ME62$v)J3- zjshL6Nk~3!-)V*>-Y?+m@pJ>=s>2p#zRlz2oJ`MVE2EI#^hgRhu*Yl+JS^jTxQ)AE ztm$-?vvRSLbUpZ&!ITjt6x%-)pTbn(-WQi801eIrxs!8f%u4r!Rh+1KYk?`@&iP7Z zM*i&aD#6Z$wR$Fa{mJ}5uf&r5YAJBbeGj7WS$4nswfmm$L_?#CGE_d3+e|j=fJDz* zX%`Y8k$#7hT7;0sV&>jUcYnY@G+)*%gd;+}3T8E*=gMMJo%EjzIjtxeS6DXuflUh) zg;&PaxG!0ilQI~a2SOIJ@c|tM_aMyZh~mjp>hd(R&h-42OEjaTm!XffO`;ggz>jO( z{Lr&?Gx~nJRV6zmo`#U^2p9d#W<`Q6*^j8}o0eyjJ#u;jmu=#dnajL%K@G$!GT^3< zTS*CF`LzeF`xY7A#cyLzje{9=tFI?i(k=V2I5jy zS}BmQ>5qd-`)+T)}I39e_}~SwRk*LHk*)`;)y!u_@JlIqhU# zT`$b9KGzycPWA^3S$ytCLp5K2UJp>I?^T7k%?#!V`w_F+%skoAYsbw(Hbsx58|J&P z-lRerbrZb`Td?1jVQie>dhT2tH})Pl1)lE~ddR{a(p3g;y;wQ=yXw}TzZ8#1x!+n% z%e{)cv?DbIOT@$;Vk+cd?FR+kEGU<-M%TZmUywi zl{}w>bw-0W-A@I!E)jQ+`xmme+h@Ya`95qOdm2~!omC)4 zrJY1)6Meph{%08T<9`lg%FY4+Ee|_*f26LVq2XY@@fr|c&MHU5Pj)0Kci6q!>6bX4 zi6%PR?2i232!4yC0O;7j!}WjnaHous2zDZypYHEB3=3lniezk;bT-j@TEqBvMx+#Z z8LRYvMoIraoS4nYIlIW~yZLE5V@W5NK5(;p+W(5Sd!ZC;_EAq5v<{j1UUwb86GKA- zxv^!E5iC#GKr~s})MB-Ednc9oF{<5bs{OQ0tmMK%A?Y>w?$D}X0GatRF6-HpA}L!< z4RVOcl%cQrcMBVHw)+zE>7~ZU>PF!&#~#?9U#}cO3FngmJi_DDPa<Ns=>R?(73xCzP zwGbn?KVGko zVq(GO!KKxV7|j{ke@Cf9*^7PLL6SkkX?3qc%A_|j8yQ7x^I5SlyEuxOnX$^|fgY2* zp8oL%BhxAUedO)~C4;|jnIf|Z!j5wJ`-C=ki1?{SblTNoaWK#tv>!{){A0+A=_4oM z&r27>`iCpz=)c#GKD34k@Oj&c1J6lFNL@?G%QAiX_mVkskBL6h(oD$8%1ST{a#Qn= z4(YW`472JE2P!|k*cVW_uf3ExXKPNicR)#uxzio)Z(J;t<*%L|>u0c7et(?lRZPgZ zU2Z?U+PS*P`FT4O?R!>Sa+}fAsVcB}a`tZEeq2+-PkkHA!L41#!%D(K{ya4SUtZ-N z@AZv-i`Y`n1_T4M+Fo6HsO1`RedV};w_aZlM9@Ab;{d71dZ4k3sk>x|+vC#7k6^rz+A3*!CJhg5q%1%>n6QZ5U7y#3ro z6Q===GDurYbYu$3q^J}l2kDRsUH_oTp~*DHULVsBbJsg{r;A(%0~7R#zoCwP%`yR(W`YBc=t7~>`c1~h`iANF#03a3UBr`4|2;`i8d;ZijGE0TDJ4ns zBkbxXCIVS2Q;UFPA7EsC(dDQ2ThVn>PKm5T$bQY_#ml@D-1CCelpNkmKPIBcGIWU@ zlgA}8F$g<^(|iX*W5m_0{*GAbsPe0r@vAd4pYvlsD#422Mg2(c+73ucmF*L{|J7k+ z)QhIdijiFP@Uv>n;dW8YqN<$EO*a8Ec)$iCjWOZYpZol#fV2YrPR0*A@ArfQZ!Q5e!Ha;%=z+kPFYiHsp0Q^2OXXlKa zgHjziuHPd~JqzFBvZLM0!MoBs)sltdyD3Jtm!fJEdVY~y)PFWk=;;SxliDf1=PozZ z)c{SJyF@9s(x#2y@YC1hyt=huE`^`HGjCw;{hh;eCd{yMd08 zEGz?GBRKI>`b!9Y+I#f)SnG-q$eyIeiNOR7GK38T{Fc!KEAcP2#iZXKPPDbPO%HuG zfu^~feorT_4|X?NK|wj*!S1xyifVCgAa?ix{kxl=nnzsU8oHTVm*KBpSYpuulB&O* zQE}{%iz9bU<&vj-6JK>0i$y6K35s<-`?%Zq_*IUHT=5`%BI{&k(;jl<%}ota=m4wd zWdLg|C@?9=&*N#$CELniX&M~W2 zim-MQZqCFsq`Xo-JTm**AbBV<5;i>M;)i}S7dNZvZ7>)e%t1{{DcQ(mW+R%(W{D86 zU|5ESYrc6sg3#dlrwavx^Jhjqi>a2kgZ_hvjni~d!a|i~VBK_Ghr7y@l9NEg&Vd5e zTNsYVMOyvMhdrUc{;r<8S&bxdma3U=r`t3zXue}gYY|vd#$Plj7 zpGGs?miCIKBy^U4yTg`>gKw;d$HwD>>cO1W8~OLZQruWw)t3WcXMMq&Rc`Zcg%;}L zCFSU$&P0L@R}ycLRj_4Sl+~B^^yl-5y1X&`;$G>^9#KD z$Lci+n|=3$FiVquIkln1dCT~60Qz^lj_SJ86=Ha7ft!oVu>`Idp6+Tq8?_yZ(iH`3 z1TZAH`;79RZ;>S;p7rsAcz-`r!XN_8dMnp@{q_@I!4^hJIQQ@PxO-tk4D_8yv>lr$ z1>4zY!OZyBR9r%AaycRGiJz(R71DPv|6+oelzix{CtK*UINp`Df1>fR6Cv1i~iQolD??Lfp%$5F_` zRFg~0$}huRFfnYU>bzQSqU;Z7v4>Gb%nSi4sKxq+BSl|5`2BuZs|nh^f?_P#ddZA( zz0{fA(}XK604RXqf1}6H-l8Zmf&F&J;qXZC2lD=51bVRUyLiboKSgU{>B^}r4>*Km zcK+o?@4>A_Xd!%T3HOiv!QSLy3zW^wz9JO7x{lH#5mIWICcscY4`O{p-m<4Ro0IJ2NWVX_i&MA=;gJr zFwvg!hTGL2?`84>dW^PJ#`TnHxLDCJyDlUI8=jAxOVP)}Wf;Y|gvg_itRpdYcnSjg z`hU~IDfKHKL~f)SdVe%^(Gv1>6xLOh?0Y7}W(;k6TKF3MlZQX9clht=y13|e$wi8q z4#6?msA()J@nG4PC>W@J57fo!)z|%&|IZP;qW{Z-bgn$5h`^fxkN?%fSpU0|-v6^_ z0@s3&;1Cday*4ws9E4Hz6klIoDLKbWvOPz3ZeUPA);tcTrp5mT?WbS=cTS=i^U7!O z-1edfvUR>q2)?m#`d}U}9ooVBq(CesJ6HDOorcgTbT4=W}O{$oG4>U6?A6Kp_%% zK5f}(9$Yz4B?6P_IgPPvf;Go|p6>eh8E9x|sHqq0O(M-sQ`K#G^XDAK~2J?H}!CFFR$-C_)X&5#c zJ{``KOr)`zT_kb4o-F2xgf`o(P=@iqoJ>Qb#Z`42+Qblt?B4Goy~YC*6XazY_-)vb838ie2-Ej=-1%m zNy9{~shG~i{e2FP3$6Zr`*F2O+R1F0N*D0vlp`HwPrkgIR9tkC%f) z_!~~!(VUc2R2dndHlMA&@SgWWrkbDjK+$1g4@VU>LH)I~m!C%M7i$fM{P!q(>mk4& zT~coNKG`_$hN+9}_p52>1=p0v#GnL}#$T+huBtZEIoY=DCNuqf5RT*iTsh_SE&3 z!EUAQ>Dg{hGh3GJ_xkAfdYzLj8?|fSglKnLl%g;E5z83#(+xQAP(PBZKA@|sJ1~O9 zsQWNXl{1$eKp175sSi*nCvv`#_ z)w%V*mqOP%iM0F?6BX6VtYxS~b!|MZ>3ZFc5wsN&+4wdTO9J!_>O(fK+BDB##frJD zjmb&HSyVQ>=vs7X9$?=m6TQsE5rO*^L87ux_<8#Vqa@7?V55yl55)v*{>4g46to<(B_To>sO0jHRInEQX3Crm@Wpv%v zTm+vldK)cfP=!CR|Kf;&c6{7TiBvyWYS;(9;1A?nvuqFGZIq}7ZWc2?D6I%RSpXGs z-~ph3M*AFb(OI}GpaTGxQeIlhE0>8aJF-Qh}H>>*ECBV!)86VF35ZJOv7Q<&)%@^kU0#qDF=hxklWT3k}+)qgm z*$CmO1_cLqzTB-~$ww_Njj)xr9u{W^ygfVpE_pjBh|x~_h-qtU3;U~-4L+Wmiz}C7 zafHqMd;0ap>s^Z}l?aW1fIzlI>~dy80tO^wdU`tbV|b~I$UT;C?i6WL5f2HJ!Jv@Y z+ei{!Mi$}=5;r$@*V}6c#Q4FXe-$sQXdae_SrsIfVb>plNevU8ELHV1F_qufBdmHQxboR0+1*34F5r&3_a`G-&)pVK;8;7D00bND?oCX!i ztP&34`Dx=#d`!JD3ut@S=~mTfDw+YEpcvtQ_wHR>T%3a73!8H1aLMz=+sg*fd!tH9M>$AI zw}9S@gTagq;}OIr+@uhhCeEXm175vy4+LcryA+|hGeE2=Nc{rI%% zH1YCs?#IdbZp){kBs)1dx%z9@YmDIQFXjHdS?4E-w6*x3aP=Y&t`+CZ;bHCY_`C_R z{c|PWAmJ^y43f?^n6f#lptyoWe1lM;!V?l3$s?7s3T_ z7c{80{QUfCrU4UG{3eKs2Bb2Ur_$lm&###fuGaJ$Z1 zEdAwGYkoeyb)S1ZgY`0%5>)KyP?UaNG{;#XewE$U4Z7;q_YR*n`yR&Yj0WMaYm>^s zX*Mg(Yd-gD`7+)4DqW>e5W}BuuU@@5E5@4U*L!2E3m)$l(MO?sBAI@=PZvrF&pkh0 ztC?1(^0<@}*MFBU5$Q&K`LvjZ2;#%xm!PC_a(2$-uvtEutC(|ZX84{RDZ|+I;prFP z0BqOVG4))8LAuyo0@3nFNAp$q?H70F8%#Vb&p&d{>yvsnjHqJM(<5FfD-(bEJiP+y zjfsgF5N1sXWdNhZjfFN@Q{(7k-x{UR;OdS0DFMu1d)g~7zyZHHZ z#%urQS5Gj4TDI?L(*o&T>QfPzm*?N% zS5=-rd@j0SHvHaRitn+pu-1K_PKWGheUM5&8=SUyJk=m{Yl!SBIVa+j2pP#F(}(}~ zfea7-`H>pFXHOa;nJPR7+}1^FJo0)}&-u5@7(Zh(v(TWR=jZE*Me~>EXV=r^;0Mlc zzy5L7py{Gn9R5S~2QVDH$f!^4fX65-B$tiq;d)PgSCKkukEV12S0}>jdZKA)m>+)t z)PsKs+4>(Xzo(Ur3;Gj3X3kMRKmZS1g*d4lX?Xf$1FFGS(xXdjYlIZ{I<{>TWMoi+ z0dA`fFae|ibU&RZ1fJ-5rV_K&ohx%i{d$o&XJ=?tx#QVT?#t-8;zK}AYB><}6?gE|%R5CR!E&QM4*x2uSFLqroAxmegZ5V{b zVP+3*Ywa#04zEx!$bH9#TVxVHz6oeju64K#Dlqe?UGCL=?MI*?tkeWAeD!-NRVrXc zawOD8_$`Y235nPL>AZ`G2;<4m8R~Sg4(iEo6qPBuD9CK{h1j0|Jph4}4OU0EY8M zI`~c4$KGmlU(rPK6We>$_;3n@$GlL`XFyrZQB!rke+29>$9?RG8ph>%I^h{~&3Y-8 z8R8h36G|C&z+?z>+D9bR$HZ6ngh^SU1hK^mz@C?WJrVMupMQJa7o?5Zda}LpO|pgN za=-YaqQFlPwhVhG4@&}Tu^4Tn@x3x&10e{t5Y77@Ny7NgczylnXZTz{Kv7{kURqnZ z3PnHN#~xqE3H@Rn#W;lJhS5TfQ*JZ6IhYDlE`3M3l8XY}jiQAR?(lH2Ib_$m@AvjZ zbmzajy9-!#*aSNDN-me9Squd}f4#{{t%ga3P}wj-uFp8@1AzCli};{i zj)2cazB_3?*`3#crVt9v7Ln%+DncCVWsSiO2Ne|+m@|my#)Z_1|Kb;vfq?<6o#uP@ zP&@GDKvm0ngd+v%Y5+9C#c?=im*cKtS~cVafVX)kw|vv z4ytMB6mp`x#!9pI`ksdrH{5u>CKsT|r|^CO>qTaI8*gzissR1;AHeKgXouAU$poXG zht#v7Yf97@9|x8q^Q5x1a$59H=p2U{rlHc7c z+{Hd{^l=19o%Gfza6}CS3tnyq&xS4&`$AtF;t}=-P6XdarQq|r(y!C%eUFD4XAXe1wIC8xl4NeE}2w zAji)64kGQsL+I-neSR`Zw2A|fAo6`MaEckv5&YUX4oC|_8sf0-3$@U*HK(4|5!taf zAcQ^d4+sa_nQ`f-ID|tzXGB6KVQN12GUzmG);q>&jAfC*-|@{KP<@_KKGNe$jxw74 zw7eToDrd9YNW;yII|YkoyYbWK4M-At#sh=&-`*EJK_$_hs3nHisfhg%(ig@Zd$>S4 zDO2Q=SY%C{b#!v7Lm6y9ecxiU5@JRIy{WLnKe`Wy^nk2A{v7LSxK>_b$tZ4zfNZ#P zP@B*5<={cOsD2NBNQzFA<=k?U)unD9m8b+C;cX{~-}75@YqV%+C}Zc1^3Cq%7*2KL zo@#pSn;D(N_ z=BAkIG+uqjeJ<8^ClR{AD3B_245}JdVpAIl6c#{G)iebR;hrhGy+KvwRAz>LYTeZSXJ&o8kVl+#r-EZRn#jhfzUXYjGqI$Y`4i}fupv`s z)Mnn>;)dO}gP}OGhqRl!J6i}U&zqwBQj=9mExIQgLniud1SXw&uENynhu#n*E9YEo zv)4Z#XG#<}IaeuozA|u^s_7{!qpx=bV~|10KlBt!+>jswq(wK?>@n5-AfJP?PiCef zMwb?2uc)X9?su-8jv}w(A%#%J%FfG?#vVWvutiT#!ekdCdP7k-y*>({DVhBOmS#58 z(p`~Ky9&DP;9#l%2qReXy4u?5IXUP1`)0NQfPrY8;?KGZ#LxXz>WH`EG{GM_t~bS# zEI~$+a;OTj;VCSMiHU(E!7cAxdCD=txdT#ODjPHIC?l_1nA|Nb!SwwzsW;#Z#`HKQ z$HwF|;lA1@Nhp2!dB5&82Ln&4>~MFYr8??)cQV|LfwuII>WR%^s^!NX*M)jk*GhKx zi*E)LRx<(mH5zb1a-pEZMj|l4WAgIywg+Q!_`RCj>Wl$L`NV;1u(66-M#=6Kv=2Zf zL?edpkS~cgVkI-|Jd7GXH*tW8>O4eKThK!xYVzzbD#qROMG9Qid% z|EW$%MuQ2u1=Bg8G%75TEld^%8#|O|6G*lZJhh%maYKtht=(SzX8LRX7GvG3oJfz_ z6XQb1vW{28SWufge$XT~5&LNAkf;idmsm(1G!p6lZR*^%t6a}?%K>WswM*j41t=Ac zo1x9So0|p%uwzMTn59s#mIx_deIEg&k}F`VxFWpn1#}M|Z*SFNA)kjdvurfcd66fn z7eiK2QD>nGo}g3t&f8V>*+>pb;Ir5ewQZDV;0;P%{v0U=v+9br-qI8CN@$|O;wOpl zQaW<_klZ>5;li%;g`trFC~iK^LUG7UG?!yty^{nW;j@45TZecre@g<^rx84){5ASp zk)jObFUuB!tvqIC`yAX}iUw*c+PEFM!JFwr5y-r1HA*zf{LC!|naw)X!@dA6c+hZe z1+LU%G?nG)?iAxMU?;+XU0Dmqpi%|-06m_`5<#v8X_DTlU?O9CYb*cCe8#AZ_Y}r% z9sp(@Kwu7Uo^-xY!yKDe#b=lX>`zj-Qdvi7bfr$qxcm6g;8=wnm2r5AzGvAIgBc*` z3VfG+fYA)A`KLKkyrPnQ-yHMPr*BU=yl&OIDGVgQp|R@7{l6uy>-?@}#Kxv~ZPle3 zQw~2DC>uI}*}9x8)&V)C@K6MBq+Yjk8iUdJRN7SlicQ9b%h00)3U^eLFBV@ zdU|?r5Qfjf!s6lK5%>|Q=LR4><0B*Jz*30=_cY6svA$V$A><<>&bPUnqtvp2 zM%vo=uuOko-hePcrI1a(v&k~~%Ipzlf*vYhDC4=${-ZU#p#`iv9W9>*HkLCZ#_JW2MY9g`3xQbK@DW%*>s6q;Jf)yJgS!~JJpCh4{X7A zJSA$3jW0miMXF!l-?w;g{buZt-BoG~!ef{Q3R11qvRe#~ArA!W!m|d=^yX?oLPA0t zldn2$jn`;dq0#~n<)klR@(IN-IDmmg$fs;~I|reney{$r(|&d3ctYX(d?|4<6MLp! zts6eQ0gw?Sv+V70pvVdH(AM-jTu*`Ex&pAAIJha20C}ucEMO&EHA$@9I^52Ggom@- zmyQ&zudDz>Ga|jof)uK+3g5NCpV_c#9Ua-b8xz5u`d`3kYx1sMx&hg(@%X8S@cRyCU} zlN=|2EJP2SJ@Ba&UObzgnNb6YZKHI{>JkHJ6-z$c)nLX!G}^?>jI+H2aLrJk;5NL@ z`JG~3yWZ~Kv^}&U0TQnxaLK-)TX0o6oG_ox=xStxiHP?IfW%p^gWlfWU=vi@@pMif zh_itikVW%;4r@7*VC;q+sN->1HsLPbjpOkK7{}2q~U(mDJCI7WhNAIfBv?UpfJ$i zAD)cI?MRL{pPVTkwxBGiKDi_73qWZg-uADm*#3MpokA|JsHk&Pn=alJx`7Yt5(f0SzSrB0V7d z4=ti0rdn~bn&Z^<_thp4$xB zY49plz^4d{#9trt38|GZh){_d>g%U>OiZWt11u~pEyssMpMJ>@?{N>0W|425o&Cr{ z*~+Y!4N6MH2`5Crs%%Q(qRb!v?q5sxeD3$AGAw59PLj&*#WB9x<}^ka9_p+3_3H*e z7hvf&_cu2Hi=RlNGE1e?YM%$0d<>(YJU<64OWZy%9@EmY|kSaCmrbJFMrcr!|gCM0#+$sdU`tT35t3neo!;uFC9@nG zwg)U>1dtlhhYmU5<~_n^F~RyiY~e@sB3wgS{ILOC)MGZt%M!I+{wtdZ zp%4t#Z49`YdX2~JX(rCE4%|m|4cgf;zLnuCQ2F{2)P8Vap0pUkqZ27I1^BIMU&cv* zLIySFetzeBD)4+El7Ql}hhmE;*28W!pXzn9?saan>vAOc@CPbM8OJw9DPOe1Qb2MWo2;K)EDkJ0yi|>3wEU!h)-&!_3oEjU@)JMF~7B*r1@$3 z$LL!C83WM4`6h2WE|~lg^Cu3DTd$u9QRS~ zt{Pp*Y~ahHkRq9~hx25vkWRBT%YwAX3S`Y~gMGnR(D?urUN;|8-|Lk9rZ7DdSeDm& zV4f!V@*xHQr)9b))qkNvX+SzYHFUHQTYwl{?mw+o3ycYae+=LNTOsmtBE*c{W^j8n zcU1NejII9*!hTOZe-79$VA=N)+eD&fud`!O0>omz%m^uVg25O0M`ot4`+{%7!^3E< zG-PA|K(vmoP_MF_js6UvO<+KP!EOvpwhZ1SMN;R-i0@ib03*0=PBGLbNkH4befu_8 zC^3k2rocL_r|kUy8Qf{CWJ{~yGK_GN?%AZ#?x3OQr&=w>lpx>ULdz= zX=%X3?4VrYL9{^eg}enAn?B_=tpN7_@Wn}OiRnY|b90pmP-hV)8+R9}@u;&b1u}Ut`yOl%* zb_5YfbTNL-wJO!`44u?l>@>g}!1?Jo-pQsb)ettS-zp|9UKY#SgwdRFdRN?Y>)n3j z+efZSLn6(t7Bn>Ncse*ne+17D*Mny2$d-%}*zul{d=g6xk^^6C->%EzP$V=G$4Doxb*wp0Sg!d%;>i6fwnI+>B3gzzh#~CEx5hEPw-LpH$x~+ z^&mv!k;`<>G@w~`7d@;%XOcLw6`8^iT5TsceFX^RSs~6FN1W^P@#+$_zGtqjX=B~N z0va_A$Avty53@LqM#x!-M{PX4Mv$s)J>XLLm|J>vCz9~IGu zfAqMxpG13|OKOUo8jtlAu;!RctSk)bi0Z--yELzb2;h)$jZuL0t>*a!oS?Fb3b8C_ z;4nXMdNSUG^X7{k(QCO{-9N`aW%l4oDs`Z2e-!c9094R$x)8q=W>AnTE6c zf?_+JCzl}Wzjnc$4JVK|y=L@zet~_B|Eq)@G#SxqX)?vF62w0(&(6+TD96|DjP=}Y z8tT^!jE#8v8?FWRC7dsFctWW`PrId=@I(h2eNOy9VbB}FEhFp?msUIuyhIU1~M>T;Hz68GXiVT6c<-Vp) zjfUi-GK-MX4v;beJ!`v(p7%bV4%>2~vGaeY5y zx@%m9ZvUn)h)jY-k0y|U8~wYg6*m7hsr#gL6T2&%#CYTgFZi-f%snLj)37F!K2J=)N5pdVJ#~OwMsWx<2!ZTLN}EnL*=3im%iSWk{s1%c^5Y zN0pniGl|kG2rO#)?vZ3^pjJ#dH&fU1l8k`19127~RxKt0FhaN$EhU!F=H0)4EnBu0 zmpfQ}pvKwM3O_s*sj=T6Cfy)ktW6bn<48j%jKX6X(? z=$jTcLkTv2{fZTP6+=aDT1$Q*-$3R{J_Ca$6o_6W+7rz?rehoG=mcN6Kx|~sC*YTW zgn-jxtrtlYwLgO&yZ5+8L2<G(^QZthngRH3^a=F$oesNB@g$p{=*2sQop_=5F!l zf@8XD#Ko`L)sILh(^v-&kyLir3bX?JBe==tJF`{$Y>)x$G6lV6i{SIQfz!NJ_4KD# z-E3=x?be$3Z*282{CCM@tmKy!KLTrBx1KmLOwMbFa{AQqY2zjcmpZlgyck(;RDTP( z=zkI!6Qd`*-G5V0*2X6H+}4>)dJ(042{3`yxOl?W1N^tM9Q?lku@PA{qyd7HU}x`X zVL>=6Ub!A)=C1THGnL0Zy}Vy{Kk~kfRJ003!i}o0#Jn;CSdv=Z?R$jAgwmyG3>&O6 z&lqx9htgX@6%unJG=jt8V&ZgDnu_Te*m%Mu|6CHA6C5arlZ{Cy!KSi-ut{o=U!;@ef#rJz%_NUW_m6H>>8h61H z0f$P2gX6&qy01?f;c5V+`J&>&^vLa`jJ>mYZB9p6{rj!U1cd0&o6RCB_azMHyZov; zY8^7qoQE=5N62~ohW8dDC05988w~3du@TSbP&%HEnfRzyUQfEVk<9jZ{GBiMXko2N ztN|+%lNAUkfHZF0F6kEC`P@3mjq@=ia2s3?PMEp89R&z?k8wWU)w>w%h@e9lb^n*4;% zd+RxsvO&N8;{wvy?r0{XGbt~LC#>%tS3CWTy=Hq<2p4G?hD%ON2FQqBY;EYSpH2X_7?Hk}jtNVLCjMiO*x^82aMVdS5 zn%`JyNyi0@K00lC5NEqrt!iTbI=n78hH9$-C0#e)@7fYz|6y*7949C}tpxKJ+nF9nkXwP>$=%u;S~W+m12Xkh5BDj6_(F0ALM^H4*mH;M<>Bml$ZC$w&G&E zkWTu#Bp?C%AN3mU-!VE@TT1e36*T3w?}Xys5Lwid0_TC z-5=8I8-PmwoG!-7vA4Cg<=*yQq8O$L5g2Y31)x~A%VSpgO@|EgId=ag?+GiV$*+b3 z{G|NSYla2jtFe9lZVe$9l_E|~5-n+JYU&n?@O}X-k&$2ijYzE1M_@=>PBQ9mAhQ(0 z^$^~Q*=-Hrj(N_K!n+i4F1ER`@hYraCoEjRZRNoytuWg3V^K+pUl^~knu%7>weP-S z3L*&i8oj%iYGJ#mpeo$0Q;ShX;e6j4c&kwjdq)|7WQq}vUII7>wc>$)FpY`WgUQkT z;!V8f(cIY)^z}|ZMG~WAan4R~r7(rDGb{j&kcA?iP&n7GZ66#T%Li#ODP(l+0reyvq=#vaXJ@-G;gX?evtH+s6*Eg6dt~%GngKS zA#eBf3#n{$x^J*uBJWyw=VV;|q5lJs!63Tgr|%Ut`)I{j#<`~4Nl$=7=607d=C-0!x0Ji0P4m?;RTJ~X!~~fH^;fD4BCP4&UOdM(BsXPGTWc&V z7nz%S^Vx^Ts|VoaTLhY5yR_JSYqLKS95w!|{)l^{0IQ$;*tB=^GG5|pDBi(b21tMS^mW8-;#?lq#2ymvFM23`4s7!*e=^WzB9ds~HY?4g#w1 zJLna9c7G8ou?))ck5esTX$dUAUuuW3LBGEGQe?U7f(N%@b=5<0x9OV zneqE{OIAoDY;I7)(WnutMl7u)aAi|o8u8VxU|D?g<_%nbzXAU_B%p^(J86gZ%c|mP z1F1j}v*chDZlb7Q!?++nR71bSnu}YN-+#wj@Uv42qsNQ+(#qeTebTog7J&XInOMRh7W-^rm4I(Djf60FHSz*>D z!<@moo_}LIxE&aYmPLwWIs{kv-@&LNBpZs}yiWsI7kxdyYoxLDb>~|y1ZtJv;ucc2 zO#A;bb0dyNii~Q&GH^@M?@{gNJ~?vZrNu?J{iSaR1cTM}Xm|k5v+%6I+V|nZ2P6Sn zGB!3c0t_)JIr-S|@I6sc(R=qEJzxI>*Zu*BlF;Zhv;Wuz_hYGf>;C>em@A=4D2Zv# z4|e=QNg-fIlJp0dpTr8h7cX9b$JZs6Hy}Pf-qn`1@HNte3KzQpqd`Ux1_2iAb?oA%EYojX7epfNKgaf}Ntm0Gfq7s{lgQJJ`4|X|?9$^!S!3u0vaA^7Y`JEar zudGn^;Wq-XhaXCPxjx9hi~)>Pl!S!4NaJn9splNdGJrqbSHCEmw0%x?NbyWNA|tU2 zr%f84o3~??OE&O`13Ov8z0_DxT(A@OXlTLRRCrH}dY1CA#mv}DZccX>uSKMtl7pMOQ*gJ7F_v{qLbH4s2-_eJ zBq=L}SL*vpANAOHJgCUHo=gR4TZf|R=kqGwH-iT`%U82r#_R%iiM_pj$aI}9BHi3Z zb(j?&=oR2$K<4P2niA#Y#5>8#%9<0TY{F#2q;|mfa+?(&Z?4&8WaYh%g8fun-d;RWvuxm}j71Wv2)e;+W6RXInY|RTTpr z9pM^29ALv;=YSp-3WAqI`|!=# zy}DTc?!~rhYEe%*N!HAV2;-2s8eo1}@1?=6@48{r>@-o1=FtLYc9|Ew`*j%Yi$fxs zmNflGPtj7^BO)S{mo(m>PgdndTUuIf%{H5Apm2zw+E$vr#z;Ux8yHo{B#YV`RN-#7 z;BVr^(CbIG8IDtet$ShNWF2UP!Q#Unuj^*L7V*TW3-SsJaeuVrx4r3{l(Oh_BvFqW z2Xvi)!^t4NaA$L@M4wq6Rlr+U{vuc|@(AI}2)52ZJ9@#z9bS$H93o7mcS=oQyg(Rq zLvjzLy7}K-i_%GU06#>{v@6c_KS<+mSJ-mwl);L@Z-XOR|I52g++ZXiMlAip3L_ZF9D!-hev{F;lxWC3x#cD)O7wEwiw6W9M!ZD1vr?u;f*4XaOVk0+#Yv$GG| zl)*~5=b3vd8A=A{W4f(t$eGtGpJyqO-)UGy^oSoMAaDm+9lNEP<-lh=pd-?xxCc>l8K{|Gvw{%mGJg0 zISC1-XzSlW+QUjeJ*ON&l`n~p9|BgDxt=Jko4# zXNPNv4HcUl3;_C(H;MvA%IwFA<)0NB*B>JjEnTF+KSJU%4~gjT7EnyS$WG?5GEK`r zdtzysm6KB;Jx)_fWHH5eXaHoYh_G;;L-e>FY%ND-JZu_XWq2^#!DI9ejc`|-7uWBA zntIQDtse|a1h?+dImkiQBwIa=hJ-{%U;hO3Qb<9pRu8vi7o)u(M%qpJZ8VgWzJV4~ zB=T?!-P3(q_3t{F(K!&aVrS?WunQ~zhkZC2^i7l}OD*%mD47hG?c-0y}j>(R^ zW6b{e=m_ekgRAR4Y-qIP0oaeQu^{a82cFMq1)u;hq;|rt19ePKQ z@JB)iAf(~JTW3pouu32oVslLW>_31YdA39hU(nUnHIV)I@nd(IOeijegzqU}!*}Q- z=C$*thf=KmKx{Pm|M?A8oIo9FNxxh36j%5ydb@vzmDrhL2HV(VXJxVad&Xz*XYl8% zrAZ()d^*qvb=ZkLaRs=9goKul;rVGq-EWsaBaR}9%FWJ}7tSV8A%K5Z$sAyPwxIqX zNH{$rwpxN&58Pbhj55?HDpbUCp#=r(J70%1nez(^byi;GEUH~b<t(;A*+q3zf=&V_ z2}MHUcN>Nu(dS>I$PQTlB`^$li0A zLq?hW2lhgLvRAKz;!fflODziKdp#YU+qo|ew}DFbSX(*V+xx0Mtocw62=FJ_HW;U8 zx5S_G>y_2li~3Q46)EB;p&w~!-9Tm#xwy+5%*#T=goI|&8y~&~nCC1dB?ULT)CJOh>ycw!n6cN@r~Ar*bo`!WM2ctvYFNIyf_ zLxfehBZ0Pw=Y&=Gtm3^>H{kNYRBIpsZXn^0;gUpVr9ahD__2D(?Ee{}Q_NHf(uoLp zXkZYIb`PQ;P;v5c&})UF$QfFjnV6x8lj{cgNpzw z!w6tYdvc&Y@NXy8H|th?FG%s@HV+S>O4UHBO^$hT<{@Vthi}hK%=$NA-3N;d>HEz2 zYq;@o>RQ^`Www;(+?-)7CLkTJ(7^fSU?%L9O7`nX;#{FYKL0X(JNH#^7bVCnO||YX z_xw33@u&E|8MxnhkiCRL5&i3H3?no13bIrl9PphbfNAIq?yGZPZ=-UV4Y!kwoW810 z!s#!S)Jo%(l%$mmGk6ZWoNQFP4n@w#u)%8&(g?lc`GddinYW-`T43RLd3(>F;J)x% zVg3vbf&mgjvQ}r#YWd3>>7;?oI89E08rZKki~%V^B!D$NRw6_Ktx=P5S0l?3jHR!N3!(~ zWi*N`c_b%B3s^nPfn_7BRzR_OM>Bf{?UtC3kbeIe?uBZ6sS*EgH`pdMvwrm&9-p>= z*Yn#d>jctXPUWXdD;_Xqvg(N;Ll<3ecQt_}0shAeD9)YSh*CbFu*;PxD{pl-g9Qt< zjt`WgJK^CRLCQFj{keSU^gDDiGPi_L>q**fNLX+ax zk}_wHOMX2K-Dd1>WezS5c79t8Rk;w1KM=rVWLyPofEg_>7JM;~FEuHZdToI6y*;QC zb)2OJkbF8nGN?9qB)#*sP3$!y@v&+&hE3T&<7|Y-yI;#D=1hZye3b^~qX?oD%5ImX zi;0Q#-_3Xs+aeGdFwQ$*9YC0yfa-s?Ozy5VCs_BYOw(MGT^q66#Xs&n{)A5U?Kt>E zOV6-3f8Lf+^jdnYfJ&iBYewEI-;L+*@4t0_uZleBYsqAt$0oDdhj7E<(i@(gNZRmv zh7HlBnApL0zVOVaPoIK|KD3l7S1|J$tDz%gzT8&6OBFy2{2>YxdF4RjRJZwMw>d)W zg$y;K2g-=UDRFa;vN?~q_)nLdJ=6=!P|4`nc7YgQ){uGA1ng*2oMm2fcKjaMRu(x* z%^jgzB%a{vT+FQOS1shYWfdeFEGQPNO8!-=Hrkgfg+mCH-kcq`kq_zA`YrHbJ(Gj5 zP44OMS=n|4z!I2t?}L?xzZ0PI#&2{FrEfRH4Jik|3K(W@9hr;P zijbX)8hX!(BJNrEySS9nF_hCN2SR3SP2>_>PPox(3HdH8%0?hce+CW}E`+?TC3s}= zBou&Qaw|{K4ctjV09W9k>4dZF+(pmYEUTcvc=`gs7nB-SCtvUf8Q25_ z1VG|)d@2)T7uxNTLEjpqwIcb8U7&x3K6nNoW)vAv^%25x^U znxq+0{YL@aY<4eOOfqhUGX*UjgNj5^J`K%GapSQeNAk|kdLa84g{>_u&8TF^Tfsyi zIsGLN8Q^-~7k%`l@B1j1=w18KLLiy-vZc`WJD^6dE-y1FX1mLzfJHLUU%$w3B#=KB zL{*m3*)o>}@Q3mU2vi-}_FrrMhs|1X@=X}cbIfKp1Sv4N6>h6)*-{L4cL@k$k&;~% z8md@ps!cfKQAW}F=4Mor9DhIXkyJNs1TF

qDn!3TzQDPUC|bzeb@LYbT9E*-h|? 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/cross-entropy/index.html b/apps/website/public/ru/learn/cross-entropy/index.html new file mode 100644 index 0000000000..c769dd6cba --- /dev/null +++ b/apps/website/public/ru/learn/cross-entropy/index.html @@ -0,0 +1,289 @@ + + + + + + +Перекрёстная энтропия: курс о нейросетях, урок 14 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Перекрёстная энтропия

+

Вы узнаете

Почему перекрёстная энтропия так дорого берёт за уверенный неверный ответ и почему именно это учит классификатор.

+

Классификатор выдаёт вероятность, а перекрёстная энтропия берёт -log вероятности, которую он дал верному ответу. Предсказания 0.8, 0.3 и 0.9 против ответов 1, 0 и 1 стоят в среднем 0.2284. Быть уверенным и правым почти бесплатно: 0.99, 0.01 и 0.99 стоят 0.0101. Быть уверенным и неправым дорого: 0.01, 0.99 и 0.01 стоят 4.6052, а к 0 стоимость растёт без предела, поэтому спека обрезает p до [1e-7, 1 - 1e-7]. Её градиент наибольший как раз там, где модель уверена и неправа. Спека binary_crossentropy_loss.t27 вычисляет потерю и градиент, из вероятностей или из логитов.

+

Попробовать

Тяните предсказание 0 к 0.01 и смотрите на кривую; затем прочитайте столбики градиента при 0.5, 0.5 и 0.5.

+

Открыть интерактивный урок →

+
Cross-entropy: why a confident wrong answer costs so much
Cross-entropy: why a confident wrong answer costs so much ↗
+

Set three predicted probabilities against the answers 1, 0, 1: the loss is -log of the chance given to the truth. Drag toward a confident mistake and the cost climbs without bound.

+

specs/ml/loss/binary_crossentropy_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Gradient w.r.t predictions | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: never compiled (`new f32[n]`, a float loop index, `predictions.size`,
+// an empty enum), and it approximated sigmoid and log with polynomials that
+// were 0.3 off at x = 1. The probability gradient also had the wrong sign on its
+// second term: d/dp of -(t log p + (1-t) log(1-p)) is -t/p + (1-t)/(1-p). It now
+// uses exp and log, writes gradients into a caller's buffer, and reduces by mean.
+
+module BinaryCe;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_EPSILON : f32 = 1e-7;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const BinaryCEConfig = struct {
+        from_logits : bool,
+        epsilon : f32,
+        reduction : Reduction,
+    };
+
+    pub const Reduction = enum(u8) {
+        Mean,
+        Sum,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn sigmoid(x: f32) -> f32 {
+        if (x >= 0.0) {
+            return 1.0 / (1.0 + exp(-x));
+        }
+        const e = exp(x);
+        return e / (1.0 + e);
+    }
+
+    // p clipped into [eps, 1 - eps] so log stays finite
+    fn clip(p: f32, eps: f32) -> f32 {
+        if (p < eps) {
+            return eps;
+        }
+        if (p > 1.0 - eps) {
+            return 1.0 - eps;
+        }
+        return p;
+    }
+
+    // -(t log p + (1 - t) log(1 - p)) for one element
+    fn element_loss(pred: f32, target: f32, config: BinaryCEConfig) -> f32 {
+        var p = pred;
+        if (config.from_logits) {
+            p = sigmoid(pred);
+        }
+        p = clip(p, config.epsilon);
+        return -(target * log(p) + (1.0 - target) * log(1.0 - p));
+    }
+
+    // mean (or sum) of element_loss
+    fn forward(predictions: []const f32, targets: []const f32, config: BinaryCEConfig) -> f32 {
+        var loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            loss = loss + element_loss(predictions[i], targets[i], config);
+            i = i + 1;
+        }
+        if (config.reduction == Reduction.Sum) {
+            return loss;
+        }
+        return loss / @as(f32, @floatFromInt(predictions.len));
+    }
+
+    // A batch of rows of width `width`, flattened row-major: the mean over every element
+    fn forward_batch(predictions: []const f32, width: usize, targets: []const f32, config: BinaryCEConfig) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            total = total + element_loss(predictions[i], targets[i], config);
+            i = i + 1;
+        }
+        _ = width;
+        return total / @as(f32, @floatFromInt(predictions.len));
+    }
+
+    // Per-element gradient of the (unreduced) loss:
+    //   from logits:        sigmoid(z) - t
+    //   from probabilities: -t / p + (1 - t) / (1 - p)
+    fn gradient(predictions: []const f32, targets: []const f32, config: BinaryCEConfig, grads: []f32) -> void {
+        var i : usize = 0;
+        while (i < predictions.len) {
+            const t = targets[i];
+            if (config.from_logits) {
+                grads[i] = sigmoid(predictions[i]) - t;
+            } else {
+                const p = clip(predictions[i], config.epsilon);
+                grads[i] = -t / p + (1.0 - t) / (1.0 - p);
+            }
+            i = i + 1;
+        }
+    }
+
+    fn cfg(from_logits: bool) -> BinaryCEConfig {
+        return BinaryCEConfig{ .from_logits = from_logits, .epsilon = DEFAULT_EPSILON, .reduction = Reduction.Mean };
+    }
+
+    // The fixture: predictions (a, b, c) against targets (1, 0, 1)
+    fn loss_of(a: f32, b: f32, c: f32, from_logits: bool) -> f32 {
+        const predictions : [3]f32 = [a, b, c];
+        const targets : [3]f32 = [1.0, 0.0, 1.0];
+        return forward(&predictions, &targets, cfg(from_logits));
+    }
+
+    fn grad_of(a: f32, b: f32, c: f32, from_logits: bool, index: usize) -> f32 {
+        const predictions : [3]f32 = [a, b, c];
+        const targets : [3]f32 = [1.0, 0.0, 1.0];
+        var grads : [3]f32 = [9.0] ** 3;
+        gradient(&predictions, &targets, cfg(from_logits), &grads);
+        return grads[index];
+    }
+
+    fn batch_loss() -> f32 {
+        const predictions : [4]f32 = [0.8, 0.3, 0.9, 0.1];
+        const targets : [4]f32 = [1.0, 0.0, 1.0, 0.0];
+        return forward_batch(&predictions, 2, &targets, cfg(false));
+    }
+
+    fn valid_input() -> f32 {
+        return loss_of(0.8, 0.3, 0.9, false);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test sigmoid_basic_case
+        given input = 0.0
+        when result = sigmoid(input)
+        then @abs(result - 0.5) < 1e-6
+
+    test sigmoid_positive_input
+        given input = 1.0
+        when result = sigmoid(input)
+        then result > 0.5 and result < 1.0 and @abs(result - 0.7310586) < 0.000001
+
+    test sigmoid_negative_input
+        given input = -1.0
+        when result = sigmoid(input)
+        then result > 0.0 and result < 0.5 and @abs(result + sigmoid(1.0) - 1.0) < 0.000001
+
+    // -(ln 0.8 + ln 0.7 + ln 0.9) / 3 = 0.2283930
+    test forward_basic_case
+        given result = loss_of(0.8, 0.3, 0.9, false)
+        then result > 0.0 and @abs(result - 0.2283930) < 0.000001
+
+    // From logits (2, -1, 3) it is the same loss as from their sigmoids
+    test forward_from_logits_case
+        given result = loss_of(2.0, -1.0, 3.0, true)
+        when probs = loss_of(sigmoid(2.0), sigmoid(-1.0), sigmoid(3.0), false)
+        then result > 0.0 and @abs(result - probs) < 0.000001
+
+    // (-ln 0.8 - ln 0.7 - ln 0.9 - ln 0.9) / 4 = 0.1976349
+    test forward_batch_basic_case
+        given result = batch_loss()
+        then result > 0.0 and @abs(result - 0.1976349) < 0.000001
+
+    // t = 1 pulls p up (negative gradient), t = 0 pushes it down (positive)
+    test gradient_basic_case
+        given g0 = grad_of(0.8, 0.3, 0.9, false, 0)
+        when g1 = grad_of(0.8, 0.3, 0.9, false, 1)
+        then g0 < 0.0 and g1 > 0.0 and grad_of(0.8, 0.3, 0.9, false, 2) < 0.0 and @abs(g0 + 1.25) < 0.000001 and @abs(g1 - 1.0 / 0.7) < 0.000001
+
+    // From logits: sigmoid(z) - t, and it matches a finite difference of the loss
+    test gradient_from_logits_case
+        given g1 = grad_of(2.0, -1.0, 3.0, true, 1)
+        when slope = 3.0 * (loss_of(2.0, -1.0 + 0.001, 3.0, true) - loss_of(2.0, -1.0 - 0.001, 3.0, true)) / 0.002
+        then @abs(g1 - sigmoid(-1.0)) < 0.000001 and @abs(g1 - slope) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // targets[i] in {0, 1}: a perfect prediction costs (almost) nothing
+    invariant binary_ce_constraint_0
+        assert loss_of(1.0, 0.0, 1.0, false) < 0.000001
+
+    // 0 < epsilon << 1
+    invariant binary_ce_constraint_1
+        assert DEFAULT_EPSILON > 0.0 and DEFAULT_EPSILON < 0.001
+
+    // name: binary_ce -- positive for an imperfect prediction
+    invariant binary_ce_constraint_2
+        assert valid_input() > 0.0
+
+    // name: gradient -- zero where the logit already gives the target
+    invariant binary_ce_constraint_3
+        assert @abs(grad_of(30.0, -30.0, 30.0, true, 0)) < 0.000001
+
+    // "Bishop (2006) - Pattern Recognition and Machine Learning": the loss falls as p nears t
+    invariant binary_ce_constraint_4
+        assert loss_of(0.9, 0.1, 0.9, false) < loss_of(0.6, 0.4, 0.6, false)
+
+    // "Goodfellow et al. (2016) - Deep Learning": clipping keeps a certain wrong answer finite
+    invariant binary_ce_constraint_5
+        assert loss_of(0.0, 1.0, 0.0, false) < 20.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/dropout/card.png b/apps/website/public/ru/learn/dropout/card.png new file mode 100644 index 0000000000000000000000000000000000000000..23797a04cc4046b24832bb179cf51f053ced1e20 GIT binary patch literal 57486 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 + + + + + +Dropout: выключенные нейроны: курс о нейросетях, урок 9 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Dropout: выключенные нейроны

+

Вы узнаете

Почему выключение нейронов во время обучения помогает и почему выживших нужно масштабировать.

+

Во время обучения dropout случайно выключает долю p нейронов, чтобы остальные не опирались ни на один из них. Выжившие нейроны тогда нужно масштабировать, иначе следующий слой видел бы сигнал другого размера при обучении, чем при выводе. Обратный dropout умножает их на 1 / (1 - p) при обучении: с p = 0.5 вход 1, 2, 3, 4 становится 2, 0, 6, 0, а вывод это простой проход. Классический dropout оставляет 1, 0, 3, 0 и умножает на 0.5 уже при выводе. Спека dropout_layer.t27 использует фиксированную маску, оставить, выбросить, оставить, выбросить, поэтому числа каждый раз одинаковые.

+

Попробовать

Сравните выходы четырёх режимов; затем прочитайте градиент выброшенного нейрона при обучении.

+

Открыть интерактивный урок →

+
Dropout: training a network with neurons switched off
Dropout: training a network with neurons switched off ↗
+

Switch between training and inference, inverted and classic dropout: units 1 and 3 are dropped, the survivors are scaled so that the layer's output keeps its expected size.

+

specs/ml/layers/dropout_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Prevent co-adaptation of neurons | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the tests called `allocf32` and `allocbool`, which no spec declares, and
+// asserted `result != undefined`. Inference also scaled by (1 - p) even for
+// inverted dropout, which already scaled by 1 / (1 - p) in training, so the
+// expected activation shrank by (1 - p) between training and inference. Inference
+// is now the identity when scale_during_training is set.
+
+module Dropout;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_DROP_RATE : f32 = 0.5;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const DropoutConfig = struct {
+        p : f32,
+        inplace : bool,
+        scale_during_training : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) → void
+    fn forward(input: []const f32, output: []f32, mask: []bool, training: bool, config: DropoutConfig) -> void {
+        const n = input.len;
+        var i : usize = 0;
+        while (i < n) {
+            if (training) {
+                if (mask[i]) {
+                    // Neuron is kept, scale during training if configured
+                    if (config.scale_during_training) {
+                        output[i] = input[i] * (1.0 / (1.0 - config.p));
+                    } else {
+                        output[i] = input[i];
+                    }
+                } else {
+                    // Neuron is dropped
+                    output[i] = 0.0;
+                }
+            } else {
+                if (config.scale_during_training) {
+                    // Inverted dropout already scaled in training: inference is the identity
+                    output[i] = input[i];
+                } else {
+                    // Classic dropout: scale by the keep probability at inference
+                    output[i] = input[i] * (1.0 - config.p);
+                }
+            }
+            i = i + 1;
+        }
+    }
+
+    // backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) → void
+    fn backward(grad_output: []const f32, mask: []const bool, grad_input: []f32, config: DropoutConfig) -> void {
+        const n = grad_output.len;
+        var i : usize = 0;
+        while (i < n) {
+            if (mask[i]) {
+                // Gradient flows through kept neurons
+                if (config.scale_during_training) {
+                    grad_input[i] = grad_output[i] * (1.0 / (1.0 - config.p));
+                } else {
+                    grad_input[i] = grad_output[i];
+                }
+            } else {
+                // Gradient is zero for dropped neurons
+                grad_input[i] = 0.0;
+            }
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    fn cfg(scaled: bool) -> DropoutConfig {
+        return DropoutConfig{ .p = DEFAULT_DROP_RATE, .inplace = false, .scale_during_training = scaled };
+    }
+
+    // forward on input (1, 2, 3, 4) with mask (keep, drop, keep, drop)
+    fn forward_at(training: bool, scaled: bool, index: usize) -> f32 {
+        const input : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var output : [4]f32 = [9.0] ** 4;
+        var mask : [4]bool = [true, false, true, false];
+        forward(&input, &output, &mask, training, cfg(scaled));
+        return output[index];
+    }
+
+    fn backward_at(scaled: bool, index: usize) -> f32 {
+        const grad_output : [4]f32 = [1.0, 1.0, 1.0, 1.0];
+        const mask : [4]bool = [true, false, true, false];
+        var grad_input : [4]f32 = [9.0] ** 4;
+        backward(&grad_output, &mask, &grad_input, cfg(scaled));
+        return grad_input[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // p = 0.5, inverted: kept units are doubled, dropped ones are 0
+    test forward_basic_case
+        given kept = forward_at(true, true, 2)
+        when dropped = forward_at(true, true, 1)
+        then kept == 6.0 and dropped == 0.0 and forward_at(true, true, 0) == 2.0
+
+    // The expected activation is the same in training and inference
+    test forward_inference_keeps_the_expectation
+        given inverted = forward_at(false, true, 2)
+        when classic = forward_at(false, false, 2)
+        then inverted == 3.0 and classic == 1.5 and forward_at(true, false, 2) == 3.0
+
+    // The gradient flows only through kept units, with the same scale
+    test backward_basic_case
+        given kept = backward_at(true, 0)
+        when dropped = backward_at(true, 3)
+        then kept == 2.0 and dropped == 0.0 and backward_at(false, 2) == 1.0
+
+    invariant dropout_rate_is_a_probability
+        assert DEFAULT_DROP_RATE >= 0.0 and DEFAULT_DROP_RATE < 1.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/elu/card.png b/apps/website/public/ru/learn/elu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ac7b7a3cfa9d987d2aa88424399f0c54aec711 GIT binary patch literal 59497 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/elu/index.html b/apps/website/public/ru/learn/elu/index.html new file mode 100644 index 0000000000..a49d27db61 --- /dev/null +++ b/apps/website/public/ru/learn/elu/index.html @@ -0,0 +1,197 @@ + + + + + + +ELU: пол, а не обрыв: курс о нейросетях, урок 6 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

ELU: пол, а не обрыв

+

Вы узнаете

Как ELU сохраняет мягкую отрицательную сторону с полом на -alpha и почему её наклон никогда не умирает до конца.

+

ELU сохраняет положительную сторону ReLU и заменяет обрыв на отрицательной стороне кривой alpha (e^x - 1), которая выполаживается к -alpha. При alpha 1 вход x = -3 даёт -0.9502, уже близко к полу -1, а наклон там 0.0498: мал, но не 0, так что нейрон ещё может сдвинуться. Отрицательные выходы не выбрасываются, поэтому среднее выходов слоя ближе к 0. Спека elu_activation.t27 вычисляет кривую, наклон и пол, а также свой пакет при -1, 0 и 2: -0.632, 0 и 2.

+

Попробовать

Поставьте alpha на 0.5 и прочитайте пол; затем найдите, как далеко влево должен уйти x, чтобы наклон стал меньше 0.01.

+

Открыть интерактивный урок →

+
ELU: a negative side with a floor
ELU: a negative side with a floor ↗
+

Drag along ELU: x above zero, alpha (e^x - 1) below. The negative side never falls under -alpha, so outputs average closer to zero, and its slope never quite dies.

+

specs/ml/activation/elu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative | φ² + 1/φ² = 3 | TRINITY
+// #8980: `math::exp` named a module this spec never imports, forward_batch grew
+// an array with `+`, and every test called a two-argument function with one
+// argument and asserted `result != undefined`. Now each test checks a value.
+
+module Elu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_ALPHA : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const ELUConfig = struct {
+        alpha : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(x, alpha) = x for x > 0, alpha * (exp(x) - 1) otherwise
+    fn forward(x: f32, alpha: f32) -> f32 {
+        if (x > 0.0) {
+            return x;
+        }
+        return alpha * (exp(x) - 1.0);
+    }
+
+    // forward_batch: output[i] = forward(input[i], alpha)
+    fn forward_batch(input: []const f32, alpha: f32, output: []f32) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = forward(input[i], alpha);
+            i = i + 1;
+        }
+    }
+
+    // derivative(x, alpha) = 1 for x > 0, alpha * exp(x) otherwise
+    fn derivative(x: f32, alpha: f32) -> f32 {
+        if (x > 0.0) {
+            return 1.0;
+        }
+        return alpha * exp(x);
+    }
+
+    // The inputs the tests and invariants share: one negative, zero, one positive.
+    fn negative_input() -> f32 {
+        return -1.0;
+    }
+
+    fn valid_input() -> f32 {
+        return 2.0;
+    }
+
+    fn batch_at(index: usize) -> f32 {
+        const input : [3]f32 = [-1.0, 0.0, 2.0];
+        var output : [3]f32 = [0.0] ** 3;
+        forward_batch(&input, DEFAULT_ALPHA, &output);
+        return output[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // ELU(-1) = exp(-1) - 1 = -0.6321206; ELU(2) = 2
+    test "forward_basic_case"
+        given input = negative_input()
+        when result = forward(input, DEFAULT_ALPHA)
+        then @abs(result - (-0.6321206)) < 0.000001 and forward(valid_input(), DEFAULT_ALPHA) == 2.0
+
+    // alpha scales only the negative side, and ELU(x) never goes below -alpha (in f32
+    // ELU(-20) rounds to exactly -alpha)
+    test "forward_alpha_scales_negative_side"
+        given input = negative_input()
+        when result = forward(input, 0.5)
+        then @abs(result - 0.5 * forward(input, 1.0)) < 0.000001 and forward(-20.0, 0.5) >= -0.5
+
+    test "forward_batch_basic_case"
+        given input = negative_input()
+        when result = batch_at(0)
+        then result == forward(input, DEFAULT_ALPHA) and batch_at(1) == 0.0 and batch_at(2) == 2.0
+
+    // ELU'(-1) = exp(-1) = 0.3678794; ELU'(2) = 1
+    test "derivative_basic_case"
+        given input = negative_input()
+        when result = derivative(input, DEFAULT_ALPHA)
+        then @abs(result - 0.3678794) < 0.000001 and derivative(valid_input(), DEFAULT_ALPHA) == 1.0
+
+    test "derivative_matches_finite_difference"
+        given slope = (forward(-1.0 + 0.001, DEFAULT_ALPHA) - forward(-1.0 - 0.001, DEFAULT_ALPHA)) / 0.002
+        when result = derivative(-1.0, DEFAULT_ALPHA)
+        then @abs(result - slope) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    invariant elu_constraint_0
+        assert DEFAULT_ALPHA > 0.0
+
+    // name: elu_formula -- identity on the positive side
+    invariant elu_constraint_1
+        assert forward(valid_input(), DEFAULT_ALPHA) == valid_input()
+
+    // name: derivative -- 1 on the positive side
+    invariant elu_constraint_2
+        assert derivative(valid_input(), DEFAULT_ALPHA) == 1.0
+
+    // "Clevert et al. (2016) - Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)":
+    // ELU is continuous at 0
+    invariant elu_constraint_3
+        assert forward(0.0, DEFAULT_ALPHA) == 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/embeddings/card.png b/apps/website/public/ru/learn/embeddings/card.png new file mode 100644 index 0000000000000000000000000000000000000000..7718b3a2b2b679e36b3bdd92823c7e2f616bb72a GIT binary patch literal 46877 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 + + + + + +Эмбеддинги: курс о нейросетях, урок 8 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Эмбеддинги

+

Вы узнаете

Как токен превращается в строку чисел и почему обучение меняет только прочитанные строки.

+

Сеть не умеет умножать слово, поэтому каждый токен это индекс в таблице с одной строкой чисел на токен, а поиск токена копирует его строку. В спеке в таблице 4 токена шириной 2, и строка v хранит (10 v, 10 v + 1), так что токен 2 читает (20, 21). Обучение отправляет градиент назад только в прочитанные строки, а токен, прочитанный дважды, собирает оба: строки градиента (1, 2) и (3, 4) на токене 2 складываются в (4, 6). Спека embedding_layer.t27 вычисляет поиск и градиент.

+

Попробовать

Прочитайте токен 2 дважды, а затем токены 1 и 3; каждый раз сосчитайте строки, где градиент не 0.

+

Открыть интерактивный урок →

+
Embeddings: how a word becomes a row of numbers
Embeddings: how a word becomes a row of numbers ↗
+

Pick two tokens: each one copies its row out of the table. Then the gradient flows back only into the rows that were read, and a token read twice collects both.

+

specs/ml/layers/embedding_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Embeddings are learned parameters | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward only asserted its arguments and wrote nothing, the tests called
+// undeclared `test_input_forward` / `test_input_init` and asserted
+// `result != undefined`, and the invariants asserted `true`. forward now looks each
+// token's row up in W (vocab_size x d_model, row-major), backward adds each
+// gradient row back into the row it came from, and init fills W deterministically.
+
+module Embedding;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_D_MODEL : u32 = 64;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const EmbeddingConfig = struct {
+        vocab_size : u32,
+        d_model : u32,
+    };
+
+    pub const EmbeddingWeights = struct {
+        W : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // embeddings[t * d + j] = W[token_ids[t] * d + j]: one row of W per token
+    fn forward(token_ids: []const u32, weights: EmbeddingWeights, embeddings: []f32, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        var t : usize = 0;
+        while (t < token_ids.len) {
+            const row : usize = token_ids[t];
+            var j : usize = 0;
+            while (j < d) {
+                embeddings[t * d + j] = weights.W[row * d + j];
+                j = j + 1;
+            }
+            t = t + 1;
+        }
+    }
+
+    // grad_W[token_ids[t]] += grad_embeddings[t]: a token seen twice collects both rows
+    fn backward(token_ids: []const u32, grad_embeddings: []const f32, grad_W: []f32, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        var t : usize = 0;
+        while (t < token_ids.len) {
+            const row : usize = token_ids[t];
+            var j : usize = 0;
+            while (j < d) {
+                grad_W[row * d + j] = grad_W[row * d + j] + grad_embeddings[t * d + j];
+                j = j + 1;
+            }
+            t = t + 1;
+        }
+    }
+
+    // Deterministic init in [-0.5, 0.5) / sqrt(d_model): a fixed hash of (row, column), so
+    // two runs start from the same weights
+    fn init(weights: EmbeddingWeights, config: EmbeddingConfig) -> void {
+        const d : usize = config.d_model;
+        const scale : f32 = 1.0 / sqrt(@as(f32, @floatFromInt(d)));
+        var k : usize = 0;
+        while (k < config.vocab_size * d) {
+            const h : u32 = @as(u32, @intCast((k * 2654435761) % 1000));
+            weights.W[k] = (@as(f32, @floatFromInt(h)) / 1000.0 - 0.5) * scale;
+            k = k + 1;
+        }
+    }
+
+    // vocab 4, d_model 2, W row v = (10 v, 10 v + 1)
+    fn cfg() -> EmbeddingConfig {
+        return EmbeddingConfig{ .vocab_size = 4, .d_model = 2 };
+    }
+
+    fn lookup_at(a: u32, b: u32, index: usize) -> f32 {
+        var w : [8]f32 = [0.0, 1.0, 10.0, 11.0, 20.0, 21.0, 30.0, 31.0];
+        const ids : [2]u32 = [a, b];
+        var out : [4]f32 = [-1.0] ** 4;
+        forward(&ids, EmbeddingWeights{ .W = &w }, &out, cfg());
+        return out[index];
+    }
+
+    // grad_W[index] after backward of ids (a, b) with gradient rows (1, 2) and (3, 4)
+    fn grad_at(a: u32, b: u32, index: usize) -> f32 {
+        const ids : [2]u32 = [a, b];
+        const grads : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var grad_w : [8]f32 = [0.0] ** 8;
+        backward(&ids, &grads, &grad_w, cfg());
+        return grad_w[index];
+    }
+
+    fn init_at(index: usize) -> f32 {
+        var w : [8]f32 = [9.0] ** 8;
+        init(EmbeddingWeights{ .W = &w }, cfg());
+        return w[index];
+    }
+
+    fn valid_input() -> u32 {
+        return cfg().vocab_size * cfg().d_model;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // ids (2, 0): rows (20, 21) then (0, 1)
+    test forward_basic_case
+        given first = lookup_at(2, 0, 0)
+        when last = lookup_at(2, 0, 3)
+        then first == 20.0 and lookup_at(2, 0, 1) == 21.0 and lookup_at(2, 0, 2) == 0.0 and last == 1.0
+
+    // Every weight is written, inside [-0.5, 0.5) / sqrt(2), and init is reproducible
+    test init_basic_case
+        given first = init_at(0)
+        when last = init_at(7)
+        then first != 9.0 and last != 9.0 and @abs(first) <= 0.36 and @abs(last) <= 0.36 and init_at(5) == init_at(5) and init_at(1) != init_at(2)
+
+    // A token seen twice collects both gradient rows; an unseen row stays 0
+    test backward_accumulates_repeated_tokens
+        given row1 = grad_at(1, 1, 2)
+        when unseen = grad_at(1, 1, 0)
+        then row1 == 4.0 and grad_at(1, 1, 3) == 6.0 and unseen == 0.0 and grad_at(1, 3, 6) == 3.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // vocab_size > 0
+    invariant embedding_constraint_0
+        assert cfg().vocab_size > 0
+
+    // d_model > 0
+    invariant embedding_constraint_1
+        assert cfg().d_model > 0 and DEFAULT_D_MODEL > 0
+
+    // W.size() == vocab_size * d_model
+    invariant embedding_constraint_2
+        assert valid_input() == 8
+
+    // token_ids must be in [0, vocab_size): the last id reads the last row
+    invariant embedding_constraint_3
+        assert lookup_at(3, 3, 1) == 31.0
+
+    // "Embedding dimension affects model capacity": each token gets d_model numbers
+    invariant embedding_constraint_4
+        assert lookup_at(1, 2, 1) == 11.0 and lookup_at(1, 2, 2) == 20.0
+
+    // "Larger vocab requires larger d_model": the init scale shrinks as 1 / sqrt(d_model)
+    invariant embedding_constraint_5
+        assert 1.0 / sqrt(@as(f32, 64.0)) < 1.0 / sqrt(@as(f32, 2.0))
+
+    // "Pre-trained embeddings transfer well": forward is a pure lookup, so loaded rows come out unchanged
+    invariant embedding_constraint_6
+        assert lookup_at(0, 1, 0) == 0.0 and lookup_at(0, 1, 2) == 10.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/gelu/card.png b/apps/website/public/ru/learn/gelu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..07239e52931b07a964cdc5ebe2e7685561e43c29 GIT binary patch literal 60422 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

H=>?whJ0~jfn!G+E)HlBtC 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/gelu/index.html b/apps/website/public/ru/learn/gelu/index.html new file mode 100644 index 0000000000..c153a8ff92 --- /dev/null +++ b/apps/website/public/ru/learn/gelu/index.html @@ -0,0 +1,242 @@ + + + + + + +GELU: провал ниже нуля: курс о нейросетях, урок 4 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

GELU: провал ниже нуля

+

Вы узнаете

Что вычисляет GELU, почему она проваливается ниже нуля и насколько близко подходит её приближение через tanh.

+

GELU взвешивает x вероятностью того, что стандартная нормальная величина меньше него: GELU(x) = x Phi(x). Большой положительный вход проходит, большой отрицательный исчезает, а между ними кривая проваливается примерно до -0.17 около x = -0.75 и только потом растёт. BERT и GPT используют её в своих слоях прямого распространения. Точной форме нужна erf, и спека вычисляет её приближением Абрамовица-Стиган с точностью 1.5e-7, а также вычисляет приближение через tanh: при -0.75 они дают -0.16997 и -0.17004. Спека gelu_activation.t27 вычисляет обе кривые и их наклоны.

+

Попробовать

Найдите нижнюю точку кривой по её наклону; затем сравните точную форму и форму через tanh при -3.

+

Открыть интерактивный урок →

+
GELU: why transformers bend a little below zero
GELU: why transformers bend a little below zero ↗
+

Drag along GELU: x weighed by the chance a normal draw is below it. It dips to about -0.17 before it rises, and the tanh shortcut stays within a few thousandths of the exact form.

+

specs/ml/activation/gelu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Based on cumulative distribution function | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: Zig has neither `@tanh` nor `@erf`, so this never compiled. erf is now
+// a function of this spec (Abramowitz-Stegun 7.1.26, |error| < 1.5e-7), and the
+// exact derivative divides the normal density by sqrt(2 pi), not sqrt(2) (the
+// slip was invisible at x = 0, the only point the tests checked).
+
+module Gelu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const SQRT_2_OVER_PI : f32 = 0.7978845608;
+    const SQRT_PI_OVER_2 : f32 = 1.2533141373;
+    const SQRT_2 : f32 = 1.4142135624;
+    const SQRT_2_PI : f32 = 2.5066282746;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const GELUConfig = struct {
+        approximate : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // erf(x), Abramowitz-Stegun 7.1.26: max absolute error 1.5e-7
+    fn erf(x: f32) -> f32 {
+        if (x < 0.0) {
+            return -erf(-x);
+        }
+        const t = 1.0 / (1.0 + 0.3275911 * x);
+        const poly = t * (0.254829592 + t * (-0.284496736 + t * (1.421413741 + t * (-1.453152027 + t * 1.061405429))));
+        return 1.0 - poly * exp(-x * x);
+    }
+
+    // One element. approximate: 0.5 x (1 + tanh(sqrt(2/pi) (x + 0.044715 x^3)));
+    // exact: 0.5 x (1 + erf(x / sqrt(2))) = x Phi(x)
+    fn gelu_one(x: f32, approximate: bool) -> f32 {
+        if (approximate) {
+            const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x);
+            return 0.5 * x * (1.0 + tanh(inner));
+        }
+        return 0.5 * x * (1.0 + erf(x / SQRT_2));
+    }
+
+    // d/dx of gelu_one
+    fn gelu_grad_one(x: f32, approximate: bool) -> f32 {
+        if (approximate) {
+            const inner = SQRT_2_OVER_PI * (x + 0.044715 * x * x * x);
+            const tanh_val = tanh(inner);
+            const sech_sq = 1.0 - tanh_val * tanh_val;
+            return 0.5 * (1.0 + tanh_val) + 0.5 * x * sech_sq * SQRT_2_OVER_PI * (1.0 + 3.0 * 0.044715 * x * x);
+        }
+        // Phi(x) + x phi(x), phi(x) = exp(-x^2 / 2) / sqrt(2 pi)
+        const cdf = 0.5 * (1.0 + erf(x / SQRT_2));
+        const pdf = exp(-0.5 * x * x) / SQRT_2_PI;
+        return cdf + x * pdf;
+    }
+
+    fn forward(input: []const f32, output: []f32, config: GELUConfig) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = gelu_one(input[i], config.approximate);
+            i = i + 1;
+        }
+    }
+
+    fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: GELUConfig) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            grad_input[i] = grad_output[i] * gelu_grad_one(input[i], config.approximate);
+            i = i + 1;
+        }
+    }
+
+    // forward / backward over a one-element slice, for the tests
+    fn forward_at(x: f32, approximate: bool) -> f32 {
+        const input : [1]f32 = [x];
+        var output : [1]f32 = [0.0];
+        forward(&input, &output, GELUConfig{ .approximate = approximate });
+        return output[0];
+    }
+
+    fn backward_at(x: f32, approximate: bool) -> f32 {
+        const grad_output : [1]f32 = [1.0];
+        const input : [1]f32 = [x];
+        var grad_input : [1]f32 = [0.0];
+        backward(&grad_output, &input, &grad_input, GELUConfig{ .approximate = approximate });
+        return grad_input[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // The product goes through a function so the check runs, not only folds at compile time.
+    fn product_of(a: f32, b: f32) -> f32 {
+        return a * b;
+    }
+
+    fn config_of(approximate: bool) -> GELUConfig {
+        return GELUConfig{ .approximate = approximate };
+    }
+
+    test gelu_sqrt_constants_are_reciprocals
+        given product = product_of(SQRT_2_OVER_PI, SQRT_PI_OVER_2)
+        then @abs(product - 1.0) < 0.0000005
+
+    test gelu_sqrt_2_over_pi_squares_to_2_over_pi
+        given squared = product_of(SQRT_2_OVER_PI, SQRT_2_OVER_PI)
+        then @abs(squared - 0.63661977) < 0.0000003
+
+    test gelu_config_records_the_approximation_choice
+        given exact = config_of(false)
+        when approx = config_of(true)
+        then !exact.approximate and approx.approximate
+
+    // erf(0) = 0, erf(1) = 0.8427008, erf(-1) = -erf(1)
+    test gelu_erf_known_values
+        given at_one = erf(1.0)
+        when at_zero = erf(0.0)
+        then @abs(at_zero) < 0.0000002 and @abs(at_one - 0.8427008) < 0.0000003 and erf(-1.0) == -at_one
+
+    test gelu_forward_zero_input
+        given exact = forward_at(0.0, false)
+        when approx = forward_at(0.0, true)
+        then exact == 0.0 and approx == 0.0
+
+    test gelu_backward_zero_input_derivative
+        given exact = backward_at(0.0, false)
+        when approx = backward_at(0.0, true)
+        then @abs(exact - 0.5) < 0.0000002 and approx == 0.5
+
+    test gelu_forward_monotonic_positive_tail
+        given small = forward_at(1.0, true)
+        when large = forward_at(2.0, true)
+        then small < large
+
+    // With the cubic term, approximate GELU(1) = 0.8411920; exact GELU(1) = Phi(1) = 0.8413447.
+    // Without it, 0.5 (1 + tanh(0.7978846)) = 0.8296438 -- so this pins the term.
+    test gelu_tanh_cubic_coefficient
+        given approx = forward_at(1.0, true)
+        when exact = forward_at(1.0, false)
+        then @abs(approx - 0.8411920) < 0.000001 and @abs(exact - 0.8413447) < 0.000001
+
+    test gelu_backward_exact_derivative_at_zero
+        given result = backward_at(0.0, false)
+        then @abs(result - 0.5) < 0.0000002
+
+    test gelu_forward_approx_derivative_at_zero
+        given result = backward_at(0.0, true)
+        then result == 0.5
+
+    // The derivative at x = 1 is where the old sqrt(2) slip showed: 1.0833155 exact
+    test gelu_backward_matches_finite_difference
+        given exact_slope = (forward_at(1.001, false) - forward_at(0.999, false)) / 0.002
+        when approx_slope = (forward_at(1.001, true) - forward_at(0.999, true)) / 0.002
+        then @abs(backward_at(1.0, false) - exact_slope) < 0.002 and @abs(backward_at(1.0, true) - approx_slope) < 0.002 and @abs(backward_at(1.0, false) - 1.0833155) < 0.000002
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/gradient-descent/card.png b/apps/website/public/ru/learn/gradient-descent/card.png new file mode 100644 index 0000000000000000000000000000000000000000..de44c1b82ab4b83b51be3bf2bbe38efc219d81d6 GIT binary patch literal 58829 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/gradient-descent/index.html b/apps/website/public/ru/learn/gradient-descent/index.html new file mode 100644 index 0000000000..cd1c2f6cc3 --- /dev/null +++ b/apps/website/public/ru/learn/gradient-descent/index.html @@ -0,0 +1,239 @@ + + + + + + +Градиентный спуск: курс о нейросетях, урок 16 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Градиентный спуск

+

Вы узнаете

Как градиентный спуск идёт вниз по функции потерь, что добавляет момент и почему слишком большой шаг никогда не успокаивается.

+

Обучение это спуск под гору по функции потерь. Градиентный спуск каждый шаг сдвигает вес на -lr, умноженное на его градиент; в спеке потеря равна (x - 3)^2 от x = 0, и lr 0.1 доходит до 2.99996 за 50 шагов. Момент добавляет долю прошлого сдвига, что ускоряет длинный склон и перелетает острое дно: при 0.9 вес пролетает 3 примерно до 5.13 и, раскачиваясь, приходит к 3.09 после 50 шагов. Нестеров берёт градиент на шаг вперёд и качается меньше, примерно до 4.25. Слишком большой шаг никогда не успокаивается: при lr 1 вес навсегда скачет между 0 и 6. Спека sgd.t27 вычисляет каждый шаг.

+

Попробовать

Найдите наибольший шаг обучения, который ещё успокаивается без момента; затем добавьте момент 0.9 и сосчитайте качания.

+

Открыть интерактивный урок →

+
Gradient descent: how a network walks downhill
Gradient descent: how a network walks downhill ↗
+

Set the learning rate and momentum and watch a weight walk from 0 to the bottom of (x - 3)^2. Plain steps creep, momentum overshoots and rings, and a rate of 1 bounces forever.

+

specs/ml/optimizer/sgd.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Nesterov accelerated gradient (NAG) | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: init called `new f32[n]`; update read undeclared locals; dampening and
+// nesterov were ignored; and weight decay was ADDED to the parameter
+// (`- v + wd * p`), which grows the weights it should shrink. update is now
+// PyTorch's SGD: g = grad + wd p; v = mu v + (1 - dampening) g;
+// step = g + mu v (Nesterov) or v; p = p - lr step.
+
+module Sgd;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_LR : f32 = 0.01;
+    const DEFAULT_MOMENTUM : f32 = 0.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SGDConfig = struct {
+        learning_rate : f32,
+        momentum : f32,
+        weight_decay : f32,
+        dampening : f32,
+        nesterov : bool,
+    };
+
+    pub const SGDState = struct {
+        velocity : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // init: the first param_count velocities start at zero (the caller owns the buffer)
+    fn init(state: SGDState, param_count: u32) -> void {
+        var i : usize = 0;
+        while (i < param_count) {
+            state.velocity[i] = 0.0;
+            i = i + 1;
+        }
+    }
+
+    fn update(params: []f32, grads: []const f32, state: SGDState, config: SGDConfig) -> void {
+        var i : usize = 0;
+        while (i < params.len) {
+            const g = grads[i] + config.weight_decay * params[i];
+            var step = g;
+            if (config.momentum > 0.0) {
+                state.velocity[i] = config.momentum * state.velocity[i] + (1.0 - config.dampening) * g;
+                if (config.nesterov) {
+                    step = g + config.momentum * state.velocity[i];
+                } else {
+                    step = state.velocity[i];
+                }
+            }
+            params[i] = params[i] - config.learning_rate * step;
+            i = i + 1;
+        }
+    }
+
+    fn cfg(lr: f32, momentum: f32, wd: f32, nesterov: bool) -> SGDConfig {
+        return SGDConfig{ .learning_rate = lr, .momentum = momentum, .weight_decay = wd, .dampening = 0.0, .nesterov = nesterov };
+    }
+
+    // Minimise f(x) = (x - 3)^2 (gradient 2 (x - 3)) from x = 0 for `steps` steps
+    fn descend(lr: f32, momentum: f32, nesterov: bool, steps: u32) -> f32 {
+        var params : [1]f32 = [0.0];
+        var velocity : [1]f32 = [5.0];
+        const state = SGDState{ .velocity = &velocity };
+        init(state, 1);
+        var n : u32 = 0;
+        while (n < steps) {
+            const grads : [1]f32 = [2.0 * (params[0] - 3.0)];
+            update(&params, &grads, state, cfg(lr, momentum, 0.0, nesterov));
+            n = n + 1;
+        }
+        return params[0];
+    }
+
+    fn init_zeroes(index: usize) -> f32 {
+        var velocity : [3]f32 = [7.0, 7.0, 7.0];
+        init(SGDState{ .velocity = &velocity }, 3);
+        return velocity[index];
+    }
+
+    // One step on params (1, 2), grads (0.1, 0.2), momentum 0.9, weight decay 0.001
+    fn one_step(index: usize) -> f32 {
+        var params : [2]f32 = [1.0, 2.0];
+        const grads : [2]f32 = [0.1, 0.2];
+        var velocity : [2]f32 = [0.0, 0.0];
+        update(&params, &grads, SGDState{ .velocity = &velocity }, cfg(0.01, 0.9, 0.001, false));
+        return params[index];
+    }
+
+    // A step with zero gradient and weight decay shrinks the weight toward 0
+    fn decay_step() -> f32 {
+        var params : [1]f32 = [2.0];
+        const grads : [1]f32 = [0.0];
+        var velocity : [1]f32 = [0.0];
+        update(&params, &grads, SGDState{ .velocity = &velocity }, cfg(0.1, 0.0, 0.5, false));
+        return params[0];
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_LR;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test "init_basic_case"
+        given first = init_zeroes(0)
+        when last = init_zeroes(2)
+        then first == 0.0 and last == 0.0
+
+    // v = g + wd p (momentum starts at 0): p0 = 1 - 0.01 (0.1 + 0.001) = 0.99899
+    test "update_basic_case"
+        given p0 = one_step(0)
+        when p1 = one_step(1)
+        then p0 != 1.0 and p1 != 2.0 and @abs(p0 - 0.99899) < 0.000001 and @abs(p1 - (2.0 - 0.01 * 0.202)) < 0.000001
+
+    // Weight decay pulls the weight toward 0: 2 - 0.1 * 0.5 * 2 = 1.9
+    test "update_weight_decay_shrinks"
+        given result = decay_step()
+        then @abs(result - 1.9) < 0.000001
+
+    // Plain, momentum and Nesterov SGD all reach the minimum at 3
+    test "update_descends_a_quadratic"
+        given plain = descend(0.1, 0.0, false, 100)
+        when heavy = descend(0.05, 0.9, false, 300)
+        then @abs(plain - 3.0) < 0.0001 and @abs(heavy - 3.0) < 0.0001 and @abs(descend(0.05, 0.9, true, 300) - 3.0) < 0.0001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // learning_rate > 0
+    invariant sgd_constraint_0
+        assert valid_input() > 0.0
+
+    // 0 <= momentum < 1
+    invariant sgd_constraint_1
+        assert DEFAULT_MOMENTUM >= 0.0 and DEFAULT_MOMENTUM < 1.0
+
+    // weight_decay >= 0: a non-negative decay never grows a weight with zero gradient
+    invariant sgd_constraint_2
+        assert decay_step() < 2.0
+
+    // params.size() == grads.size(): every parameter moves
+    invariant sgd_constraint_3
+        assert one_step(0) != 1.0 and one_step(1) != 2.0
+
+    // If momentum > 0: state.velocity.size() == params.size() -- init zeroes all of it
+    invariant sgd_constraint_4
+        assert init_zeroes(1) == 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/index.html b/apps/website/public/ru/learn/index.html index d918b0e455..8ad8d74417 100644 --- a/apps/website/public/ru/learn/index.html +++ b/apps/website/public/ru/learn/index.html @@ -63,7 +63,7 @@

Основы t27: язык за 27 уроков

Перед курсом по FPGA: что такое спека t27, как компилятор её читает и что отдаёт в ответ. Каждый урок открывает таблицу или схему из своей спеки и одну спеку, которую можно запустить в браузере.

Курс 0, 27 уроков, в каждом инфографика и спека t27: модуль, константы и типы, функции и тесты, затем стадии компилятора и 7 языков, которые он пишет. Идёт перед курсом по FPGA.

Открыть интерактивный курс →

-
  1. Основы t27: язык за 27 уроков
  2. С нуля до чипа: программирование FPGA на t27
  3. ИИ-числа на t27: от форматов чисел до тернарной сети
  4. GoldenFloat на t27: одно правило, семнадцать ширин чисел
  5. Проверка железа с t27: тестбенчи, временные диаграммы, формальные методы, мутации
  6. Тактирование, сброс и пересечения тактовых доменов на t27
  7. Шины и периферия на t27: UART, SPI, APB, AXI4, Ethernet
  8. Троичная машина: от трита до работающей программы
  9. Арифметика и DSP на FPGA: от цепи переноса до фильтра
+
  1. Основы t27: язык за 27 уроков
  2. С нуля до чипа: программирование FPGA на t27
  3. ИИ-числа на t27: от форматов чисел до тернарной сети
  4. GoldenFloat на t27: одно правило, семнадцать ширин чисел
  5. Проверка железа с t27: тестбенчи, временные диаграммы, формальные методы, мутации
  6. Тактирование, сброс и пересечения тактовых доменов на t27
  7. Шины и периферия на t27: UART, SPI, APB, AXI4, Ethernet
  8. Троичная машина: от трита до работающей программы
  9. Арифметика и DSP на FPGA: от цепи переноса до фильтра
  10. Нейросети на t27: от одного нейрона до блока трансформера

Все уроки

diff --git a/apps/website/public/ru/learn/lamb-and-large-batches/card.png b/apps/website/public/ru/learn/lamb-and-large-batches/card.png new file mode 100644 index 0000000000000000000000000000000000000000..245eb98fdce8e15b1e37a8510eafd84f626e08cc GIT binary patch literal 60963 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/lamb-and-large-batches/index.html b/apps/website/public/ru/learn/lamb-and-large-batches/index.html new file mode 100644 index 0000000000..3a6803d768 --- /dev/null +++ b/apps/website/public/ru/learn/lamb-and-large-batches/index.html @@ -0,0 +1,321 @@ + + + + + + +LAMB и большие пакеты: курс о нейросетях, урок 21 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

LAMB и большие пакеты

+

Вы узнаете

Как LAMB масштабирует шаг каждого слоя его собственной нормой весов, чтобы один шаг обучения подходил слоям любого размера.

+

Обучение на очень больших пакетах требует большого шага обучения, а один шаг может быть слишком большим для малого слоя и слишком малым для большого. LAMB берёт обновление в духе Adam для каждого слоя и перемасштабирует его коэффициентом доверия, нормой весов слоя, ограниченной 10, делённой на норму обновления, поэтому каждый слой сдвигается на одну и ту же долю самого себя. В спеке веса (1, 2), умноженные на масштаб, делают шаг с нормой, в 0.001 раз меньшей их собственной: 0.00447 при масштабе 2, а когда норма весов переходит 10, около масштаба 4.47, шаг остаётся на 0.01. Спека lamb.t27 вычисляет обновление для одного слоя и для двух сразу.

+

Попробовать

Прочитайте шаг при масштабах 1 и 2 и сравните; затем перетащите за изгиб и объясните, почему линия становится плоской.

+

Открыть интерактивный урок →

+
LAMB: one learning rate for layers of every size
LAMB: one learning rate for layers of every size ↗
+

Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing.

+

specs/ml/optimizer/lamb.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// LAMB parameter update with trust ratio clipping | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: built with `append` on `[]` and `range` / `len` / `pow`, so it never
+// compiled. The math was also not LAMB: v_hat used beta1's bias correction, the
+// "trust ratio" was ||g|| / ||v_hat|| and was computed, then never applied to the
+// step, and m and v were never written back. It is now You et al. (2020):
+//   r = m_hat / (sqrt(v_hat) + eps) + wd * w,  trust = min(||w||, clip) / ||r||,
+//   w = w - lr * trust * r,
+// per layer, over buffers the caller owns.
+
+module Lamb;
+    use base::types;
+    use math::constants;
+    use ml::optimizer::adam;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_LR : f32 = 0.001;
+    const DEFAULT_BETA1 : f32 = 0.9;
+    const DEFAULT_BETA2 : f32 = 0.999;
+    const DEFAULT_EPSILON : f32 = 1e-6;
+    const DEFAULT_CLIP_THRESHOLD : f32 = 10.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const LAMBConfig = struct {
+        learning_rate : f32,
+        beta1 : f32,
+        beta2 : f32,
+        epsilon : f32,
+        weight_decay : f32,
+        clip_threshold : f32,
+    };
+
+    pub const LAMBState = struct {
+        m : []f32,
+        v : []f32,
+        step : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // m and v are the first num_params entries of the given buffers, zeroed; step 0
+    fn init_state(m: []f32, v: []f32, num_params: u32) -> LAMBState {
+        var i : usize = 0;
+        while (i < num_params) {
+            m[i] = 0.0;
+            v[i] = 0.0;
+            i = i + 1;
+        }
+        return LAMBState{ .m = m[0..num_params], .v = v[0..num_params], .step = 0 };
+    }
+
+    // powi (b^t for a whole t) comes from specs/ml/optimizer/adam.t27 through `use`
+
+    // Writes the moments for step (state.step + 1) into state.m / state.v and the update to
+    // ADD to params into `update`; returns update[0..n]
+    fn compute_layer_update(params: []const f32, grads: []const f32, state: LAMBState, config: LAMBConfig, update: []f32) -> []f32 {
+        const n = params.len;
+        const t = state.step + 1;
+        const c1 = 1.0 - powi(config.beta1, t);
+        const c2 = 1.0 - powi(config.beta2, t);
+        var w_norm : f32 = 0.0;
+        var r_norm : f32 = 0.0;
+        var i : usize = 0;
+        while (i < n) {
+            state.m[i] = config.beta1 * state.m[i] + (1.0 - config.beta1) * grads[i];
+            state.v[i] = config.beta2 * state.v[i] + (1.0 - config.beta2) * grads[i] * grads[i];
+            const r = (state.m[i] / c1) / (sqrt(state.v[i] / c2) + config.epsilon) + config.weight_decay * params[i];
+            update[i] = r;
+            w_norm = w_norm + params[i] * params[i];
+            r_norm = r_norm + r * r;
+            i = i + 1;
+        }
+        w_norm = sqrt(w_norm);
+        r_norm = sqrt(r_norm);
+        var trust : f32 = 1.0;
+        if (w_norm > 0.0 and r_norm > 0.0) {
+            trust = @min(w_norm, config.clip_threshold) / r_norm;
+        }
+        i = 0;
+        while (i < n) {
+            update[i] = -config.learning_rate * trust * update[i];
+            i = i + 1;
+        }
+        return update[0..n];
+    }
+
+    // One LAMB step over several layers packed back to back in `params` (layer k has
+    // sizes[k] entries), each with its own state; params change in place, each step + 1.
+    fn forward(params: []f32, grads: []const f32, sizes: []const usize, states: []LAMBState, config: LAMBConfig, scratch: []f32) -> void {
+        var start : usize = 0;
+        var k : usize = 0;
+        while (k < sizes.len) {
+            const end = start + sizes[k];
+            const upd = compute_layer_update(params[start..end], grads[start..end], states[k], config, scratch);
+            var j : usize = 0;
+            while (j < sizes[k]) {
+                params[start + j] = params[start + j] + upd[j];
+                j = j + 1;
+            }
+            states[k].step = states[k].step + 1;
+            start = end;
+            k = k + 1;
+        }
+    }
+
+    fn cfg(lr: f32) -> LAMBConfig {
+        return LAMBConfig{ .learning_rate = lr, .beta1 = DEFAULT_BETA1, .beta2 = DEFAULT_BETA2, .epsilon = DEFAULT_EPSILON, .weight_decay = 0.01, .clip_threshold = DEFAULT_CLIP_THRESHOLD };
+    }
+
+    // which: 0 = m.len, 1 = v.len, 2 = step, 3 = m[0], 4 = v[99]
+    fn init_probe(which: u8) -> f32 {
+        var m : [100]f32 = [9.0] ** 100;
+        var v : [100]f32 = [9.0] ** 100;
+        const st = init_state(&m, &v, 100);
+        if (which == 0) {
+            return @as(f32, @floatFromInt(st.m.len));
+        }
+        if (which == 1) {
+            return @as(f32, @floatFromInt(st.v.len));
+        }
+        if (which == 2) {
+            return @as(f32, @floatFromInt(st.step));
+        }
+        if (which == 3) {
+            return st.m[0];
+        }
+        return st.v[99];
+    }
+
+    // update[index] of the first step on params (1, 2, 3), grads (0.1, 0.2, 0.3); index 3 = its length
+    fn first_update(index: usize) -> f32 {
+        const params : [3]f32 = [1.0, 2.0, 3.0];
+        const grads : [3]f32 = [0.1, 0.2, 0.3];
+        var m : [3]f32 = undefined;
+        var v : [3]f32 = undefined;
+        var update : [3]f32 = [9.0] ** 3;
+        const u = compute_layer_update(&params, &grads, init_state(&m, &v, 3), cfg(0.001), &update);
+        if (index == 3) {
+            return @as(f32, @floatFromInt(u.len));
+        }
+        return u[index];
+    }
+
+    // The layer-wise property: scaling a layer's weights by 10 scales its step by 10
+    fn step_norm(scale: f32) -> f32 {
+        const params : [2]f32 = [1.0 * scale, 2.0 * scale];
+        const grads : [2]f32 = [0.1, 0.2];
+        var m : [2]f32 = undefined;
+        var v : [2]f32 = undefined;
+        var update : [2]f32 = undefined;
+        const u = compute_layer_update(&params, &grads, init_state(&m, &v, 2), cfg(0.001), &update);
+        return sqrt(u[0] * u[0] + u[1] * u[1]);
+    }
+
+    // Two layers (1, 2) and (3, 4), one step; which: 0..3 = new params, 4 = step of layer 1
+    fn two_layers(which: usize) -> f32 {
+        var params : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        const grads : [4]f32 = [0.1, 0.2, 0.3, 0.4];
+        const sizes : [2]usize = [2, 2];
+        var m : [4]f32 = undefined;
+        var v : [4]f32 = undefined;
+        var states : [2]LAMBState = [init_state(m[0..2], v[0..2], 2), init_state(m[2..4], v[2..4], 2)];
+        var scratch : [2]f32 = undefined;
+        forward(&params, &grads, &sizes, &states, cfg(0.001), &scratch);
+        if (which == 4) {
+            return @as(f32, @floatFromInt(states[1].step));
+        }
+        return params[which];
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_BETA1;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test init_state_basic_case
+        given num_params = 100.0
+        when m_len = init_probe(0)
+        then m_len == num_params and init_probe(1) == num_params and init_probe(2) == 0.0 and init_probe(3) == 0.0 and init_probe(4) == 0.0
+
+    // Every update is negative (descent) and the step's norm is lr * min(||w||, 10) = 0.001 ||w||
+    test compute_layer_update_basic_case
+        given u0 = first_update(0)
+        when n = first_update(3)
+        then n == 3.0 and u0 < 0.0 and first_update(1) < 0.0 and first_update(2) < 0.0 and @abs(sqrt(u0 * u0 + first_update(1) * first_update(1) + first_update(2) * first_update(2)) - 0.001 * sqrt(@as(f32, 14.0))) < 0.0000001
+
+    // Each layer moves, and each layer's state advances
+    test forward_basic_case
+        given p0 = two_layers(0)
+        when p3 = two_layers(3)
+        then p0 != 1.0 and two_layers(1) != 2.0 and two_layers(2) != 3.0 and p3 != 4.0 and p0 < 1.0 and two_layers(4) == 1.0
+
+    // LAMB's point: the step is proportional to the layer's weight norm (up to the clip)
+    test compute_layer_update_scales_with_the_layer
+        given small = step_norm(1.0)
+        when large = step_norm(3.0)
+        then @abs(large / small - 3.0) < 0.001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // 0 < beta1 < 1
+    invariant lamb_constraint_0
+        assert valid_input() > 0.0 and valid_input() < 1.0
+
+    // 0 < beta2 < 1
+    invariant lamb_constraint_1
+        assert DEFAULT_BETA2 > 0.0 and DEFAULT_BETA2 < 1.0
+
+    // epsilon > 0
+    invariant lamb_constraint_2
+        assert DEFAULT_EPSILON > 0.0
+
+    // clip_threshold > 0
+    invariant lamb_constraint_3
+        assert DEFAULT_CLIP_THRESHOLD > 0.0
+
+    // name: trust_ratio -- capped by clip_threshold: a layer of norm 50 steps as one of norm 10
+    invariant lamb_constraint_4
+        assert DEFAULT_CLIP_THRESHOLD == 10.0
+
+    // name: lamb_update -- bias correction makes the first m_hat equal g
+    invariant lamb_constraint_5
+        assert powi(DEFAULT_BETA1, 1) == DEFAULT_BETA1 and DEFAULT_LR > 0.0
+
+    // "You et al. (2020) - Large Batch Optimization for Deep Learning: Training BERT in 76 minutes"
+    invariant lamb_constraint_6
+        assert powi(0.5, 3) == 0.125
+
+    // "Used in BERT, T5, and other large-scale Transformer training"
+    invariant lamb_constraint_7
+        assert DEFAULT_BETA2 > DEFAULT_BETA1
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/learning-xor/card.png b/apps/website/public/ru/learn/learning-xor/card.png new file mode 100644 index 0000000000000000000000000000000000000000..d61282387bbafd862664e9acc04f707e5695919a GIT binary patch literal 52748 zcmeGDXHZjb_%#Y6N*6(TM-=JOi}WTSARR=cOGl*FK!Qk9I#NRKy*H(UfPnPgL#UyX zP(p8K^ZTFYd^s~`=6reQecyTVX-_63d*AoE*0t8UZhmO0D-q(;;A3E55GucYqm6;_ zs0srE(-RjHc<0aaJpv32VhrUsvbx@Bdy7OyIw!Z%2O8ZNO26#}rAuKdZ~t)T?y6K_ z;&W`V7`PKO>#yz9b1tTeRDvqK+wH7xNKk6Id+-BzX)MI40*SEpCg4zh=BB%b9sgDK zw*jF?UaHt%wc|6X%|CP&w6y+Yzh{n552E(>_R?x=_m9O;Zc>@V*ub3tFIo1W2mf8j zXv#f%^xqY(Hg3>=7Z|em0mT1ZJ$uVUe1Ge}bFe>>`|slGvtSwA|E`Ghh;jetJHC-& zGX3|KOw9lOvj3l5Gey5=627Ng5C7ZA24e1}t>?l&v*rHZZMMCo*N^}C28^2!{Qs{& zh0y9l^Q2W-wMgsfN71BP;WjUCSIgzOM^aojbFLL?Nk~aPu>_@_cz6gQ6tJ)=XAD6j zx8`cbhg`*>$&8ch%!7~{Vp?A1{sEx`A3oSn)3?8q2u4Gg8p6u%3B`!Y)~}SVP|M4d z{*>!SZdN9rdV0WxX-I#g+E!i*IUBW=GJ^{ggBT*IiC>zjrIAhOaEzl+jqf%?-~RU| z#}LBjM{Sx-SC4c68^NKDqZt1@#7;(MBY*J0|7<{$BN=f zGIFxk-9u_%m%8--`TMX=Qif#M865)?lB%|*PWhTYfZiQ0DrXxYNt0w z!JaNInS#~^NH>xNcPP$O z-LAv^C6+9XR12lh3!$Wn6U|x;U3NIf2RU4RtpH-`O9(|u{Np`z9Z zzd7BOm@N~TC^Qt46*ZT8XYXikrKo7qQx@5}^d3L3R50cG4U=&y5rgG89^a4JPoF;I zZy0w~sZ9f0Dn%vYvD0uy#@wUNyzoVSeztM6nvR?ST!I%>5~PiJWOv8Aih)OO? zd3W_E7TokO!;40`!7wGaU@eg04|jT5o1>8_sVHjCc)%6reQo(CPnH5B;9#<&Ur)3) zEZDkLkfk!~D`p797XopqJs7f>o=Hm2BrZt$Rq|CeFnwr2A5l3z>E5$m#=-UPN38XF zWk36fk4I*6(U^gLT~XGx*%{Q}j6f@jDxyo?JYLD7v+=_?dpa>gTncZtZD#ZHDfX_? zvnZd0<|#c6i=p7+AMNEeRk5Ke%?dQ!iM#ci!ynP_N2VmFj7*Fy)Zaz+WxY9f^jfLq zBx2y2(PePY#5qZUO`769;C~leQ}kBeNn24?*3oJN^chTfyFMSZ9CLYeYjx zD=q0Y^*lcrXm=52tVE1>)B;u|Eu2qXeVik1{>4sM^qxAN2EWrCX-WUt72D+R;Fp_0 zV7oG7xiQqPr|vZaKG}dGQ$<uuxDq4w#9 zg^?a&T|)-=!6_u>hWgJRQ@cf`3NLM2lq?e8On-baLIvs`zIV04L*}!W+n+0sp5L_dNlK<^b=?3^16w~ z&7Tp_`rCAzuEMCSxlQBac3A>5$Dx$^+Wa~N!zy%3Cv?FF!`tjcm(D7i?DBdmIeG{| zBD>WxU1+_BpS=krBp&|fTSSDC>0QHTB2ka6waDmUlUwfoKnx7tpY$R~ap#Z12pa0l zyH11-YxFj(eZ+fwD39qV=uOxY&o1QInWvDC_?iFtEqpB^vQ=I3LR7o1*oUv*`De|h#oi~F)AnMad-%S&^>)f&<8>~@$&|G=?HJ#5# z?pxU|hWx*+&m=5kA$-UwLe#OXanQdC)jV(izurMu&9RKQH{=ZPVkgH6&LxvMKO~t# zQ)nqcuqtbVQKnbFQGM(8Tsu#){7$msM!z4`1>Vj_Sm88Yb`l%8?}xy7$wY<+oxZ%n7z=wERQDp+X9ujkrCyQS!DE&{mG6du@tO0bxjpt zW(S2&GqfLcjYLRFO93*0(=C~5{NOdmpD`n16!GX!QtyJ_^e(=m;$dMoKU1 zJ`gpZ{hWn<4I2Noh7J09`Bz`)>ikU-uQKj)C`W-B!w~dmh===YFf7aWu8YWPzeF5* zU9^+(&uVVXbo-Rvs%tu?y-;oiO0qKfNL0EqW=v;tMw3Bsaw@VYd`Hewr$CKHfiV%> zyU+Cx%lMhZFVxhWa&`60Qu8$X_aNnbzfW6&jP8=AquO^nM@o!f_lwe~zOH!cMrzU^ z&bbtvHI;T=D@-U(a$7}3vIZ|qIk#U%EocRgAgrD;Per_u07qZXXV^2Of7P{B^LIM2 zA}xDDC6TbxnJAI#15|}TK0tvxt1}8sYCTU=`BBA5G))W3 zSfk?qDE#rwOP;lW7sEte3_>nHY|yiOxw9DQud}XJaWiqrjh@p9B##94w5h+6=;N*$ z{ypDMFW&Fzzm2QMWKqCk(q+n`U+eUGMmY3V5<$X5dEBTI&~=ejmhxARdH1ZTFR;_6 zohfI_)(2yj&_yAAEaTgF8MEn>SUoqVM?%)p# zf$|wZ=oGs89DKb(zE+If@C_988Gp&mAPxFy&yq8i+hx3Pn4<-gEZi>ymlwM;6qQTA zleG*}abYK~Jg-oS@bF+b%KA>I&*b_mWj7yju$)0b{k&QDB%tw_v0qn>E^i?C+F#?w z>sweJ*>SI0_M5jp&NNUQqDkaFeVKZu#LyxoKL}m4l8D=dn9y}a?hDe{e09N1wgj2T zLY_na{id|P^HN(;R|U>*lr%xz zTUf!t-LE%ZKKW+5BPdND$B8)PASpt3<^5n;OGIbNOzZHxcHx`}G&M6OB`%f&ab#u_ z*;60q-qoX_Josk?dmGYU7SI#A6 zBbp~P;qD+f6ekHQkZ8D`!wFtET~m4&a(OlYUlO0)4A4FA<&8@Omz5p*0JGPdoCDmM|#7Pg`!aT*MbO@8;gw#Yt*}bQ5?RYzBK3 zE$K^eJdqzqT1op^q^&ExX%B3W=2hkB+0{-Uf<0P9iW{_sGSaIHt33Z=`pe!obIiu? z(=eAK&KK^pwLyi-hGWWv2x)WlGP`HkP7o-OD)-$x-4H$FBtG6I^*Z-P(GOy~VFbG* zl!%^nva)%TxJ@Av?dOw|uTp1S}scy)72NwtgGf z&NZE)ode^|Xz73{z4+#+?lO=ow=vFb;}+7}N<68BYGgT%BPkMy#D(5IHX?}LE+3Jn zkm~;F#I4}3W<@MqY9Z^rt?Hv)N3eH)ym4w+|0&TYrs!xQqbH-=*g{yNr+eyun3#}p z^I6*#(~A!!ol{-P(uCL7cXjcag>PCN+M7u&fmSe+B&aTRays~#jfi2XZ~=AN)K7}N zNU22fvnQ&Rd)L2W;FHv@&|Xlz7Hb+d`$}*GwaD~UKyVD7yWgj}#fI=FsdDqOuKz0w zK;MjQN$&l1Sv#Bvh{HCh!jbDkTXlDblXSA@lWlA?GCFrA=ZYtbL34EOTqucM*T!~t zIZlkGw;d{q#s7U``OD1m4!5-Z*~2_q4ubH{+Q+2%=|d@<`+>d*=_YZharKL7Olq(U z%D4d~IVaYrj}6PM9DG6{3yK^4tNUO*=jI+J%j=V@p@i<>;FM^hMv2Y%Wc$Df)#jBI zb2KYp=5Sxf=l*41RR$v$3)6;JsH#=W$ znJnHeuxi9=Z1mop&MOoa?FJ{0q$y$H#;OhZEoU2&9U0a-E*k0zfB4mcL|UpN8P|7* z)EUc{@>Q>sL0m6O76Wxa=sQVrG?nLbzd@m$D@dYH@bBCvWWI`*$G`;4r(I+K;o8ks zk(oYUDS@taTOFvGxs}{$TOeJB9Xv5Q9Bc4jGFjW2w|q4 z5|vZ$R!QV!qxo3;>E8g&oK=v>N>ivE_i%aws>|%*;$olsw4Gq!lsFT4b^_}TB+a|d55fjeO#D?n)gC@;OJ^Ys`r`&oI$i56M)Ro%_9O5s zo!gwPq@xk{l2MCVfyQegLXWa*kt#Tx&VK7)#~F%NNPx`4g(7nJEua9FI> z9d|1FL!z9N-peHqGv}}%;0Z=+h)$hJ<8hbRiu?l!pZhQAc!@h#l*Pi6snQXqjuD>p(EAH z`?@R+{ap$R7jQN7Lb3Hp6Hk5vuzzgH4o(btO+T4KPzU3Lj%6S`0?oq52&_`U`2J5v z`0w+h&V=*Z3esp_{G>0N)P17;YuvS}AbEFCi0Os1xEmG*#%nP8&+W|@c#Ywv){B|7 z+bx%xvEiZBgK9s~P;s4M1ZL-$MT4$O3V*17$JTj3>-FpJy=OjLFY%6{hgkpO(r*}W zmeGf~*EG>Ib&l^k5%!Ko(j_0KAVQcS>gY4cldr$mV&jZh1sQx_N`fb=M*c0nZgH|C zlxADK!V#;fv}SHe-&EGb?yO=bqWHoytW{ItG6rtet!x&jW^ATRC}J?GEic;}+GNa- zf?Mn?D?VF4%4+kT4hnAy;&f{$`umCGp=d?ge4)WF`(|RiV-%VWuZxA5`3PL)$iu-{ zM`}wbMC14-{NOJP7W9>H5fEnJmFF*@BbI<*6@@Zz>%BwtguI3<4|H+wUu)&|x)iUj zD@z|g3oc=I#it0}Z4vIgD8-KVUs9fKZk{MX4)G)o_1jPKvAq_*B!!T(&WpWF;r(n=jcSt*FB_ z8jHut&~4NEz5vM7X?N`(d$MT5QWCrgGZ{Ns)tfnW)aF*+qAjhq zO>4l^f*?As8HiFik4XfCo3@QYcGW`|C!%P({)7$;cjl80drVOe6S^&PdmT~YyUx_< z2{THZrNrazrWn{`ib!RnJvIk$yU2(>?}XVXk1Ueb7LB)jZ+5Bje&5Lhr!i=?%P8R) z=1I~sh)IdjPimL+@R@4-LRRom)2NQkyfcWZ!fULlQ!nLGmOe1h1T>a2d9<1q)UtmG z3k0<`3Zyj`X!Z{-a00Q9Ow8-W_s2a^pO28ujwURK)n&x_kmy6nnpE-QjzX)!%wF{@M{ zDt>nD*muW)OsxfdS|PnfkH8U-C>vqk0=IulUbh`9`QxzQMA}F|vw&9-8Zb7wY@ILL$|T64L%p^&km+u&dGH z$~lt?_7Xk;Ko^_2%x`ICbE$T?UNf&fj}G*kfRC-^O8`zwkh1v+YQgyZ<*kXduREQj`Ue{ES66M7 zr^xck$|dR7>2jW4tQOLm%}&gOVw=0ZJMSi2sYOp;^nkDIJzFbxB{$yuW1C|R_Ty?T z7VHp5%{&?M+^!aUvWCrCp9ZTu{>C}}xuWnGU>A%(v>cCLd2@Y+-Odn* zOf|9N1^<@`GRGoO{-8D0v@jgrnymkOt~>eifBrg^ajQMNtOxw+Ql1rNB6`wARQT$0 znujP!%-;+!-ODup*C0Sg@&8l#{|hPN3`yU_|M@v1TuNj2r?h>Fr{n(@qW~G;hM~{@xNQW=agT4|ALoNe9|K7K^UlW-atNi68)&9(?B^CVK zq5m5{WWw7MJrqj*ph@H&S~4-z7Xb(H*)71PYjUyrUwfhhsLuM2|NJo)q%J#R&=0^A1#&i7^r_2`@ z>`h0@9sOSi1AlIphK0LYGz4{tod_j(;LHUDO}?>uO%UD3&Q)TUanjjKvB?@#d=%D{ zF*?`MT2#~$#V+7_>`IdNPFZ7g#)=Dd5%g8&<$CAp^(5XkBTg#k=aiv%939fFCwBG_ z7g@DWaKlj8K0Qcmd=%z`L>=Ja)mp#QjzaDU)?!Gs+}|RGEZegRro1;FOrVr;e_nPb z<$zD*EF>e2o-sarl1QmfgIW1NT1tqAHI~Rr2#dNlQJ;Pl`Iy#U!yIwiLe(!uh7Oai zaK-oj2}mGayBSjcL;|ALk1eg%zCPw9f)aeJJkJi* z`AzLEdzN5(RxTIIBNT!Y{0vl+i3K`*^g3Do{$-=raDJpP(3^r8nbE8etwFVw@3MxP zo1VVn5byQyQR69Wa46^PPLGzp>;KI^Uv!NC!>}M<)aGlTi>51^^}KfPzWt0I@&Jrn z6wIc0h7AAnt4L+C;f(!2WFdxQ+Ph8;Eo5;=1mN)%i}DrMYLoKwLky>`*ne&h2rdxtv%JoDH!+fP z=jujaW3}GyTZE!v&hJ<~TBUm_puaKFZ(t~t^pSu& zGCTqv^{dQNDsnmd9vx(99^GFOYlO2w%$ox-a2LZ>bRMWv5Sdf=OcDXMuN|SFj5L~a!d5wKJdUf`+hWK z>{QM)mPXD#pZA>@!RWE2wgboLWAmD5=#;_VD*(_P(P&F)Aqv!559d zdRnj?81Q;&t#~5mTk)t%-yi8oLT?@E@1~yx@>?^*#s8fPxZlqR-T)HZId-s>%gdQL+rhH5zlT4Q9!n8(1%KI#MN$PUpS7n>t$)S{EDdZYi%5yEu>P7B_U!}{A#uq#9Ddheb z&t#<0*jmt7344dwFlrNYsNjOb>Aa!2_s0kTs!Nh#dn}z@NDFJs`9baH&zWxIBmf8e zR7(S_SUOf-sJq+4=nIF-d%5U0ZyyL~^=X*aEjHf8$|oq$Ao0c@anOKNf>!uyg9K;$ z@;mh8XTO94`Jj1rj2keKOUO7j^L{s+W5nUsGnjLCjKFV#;Oh+bk7y)lQ&$+Ej^mia z;$ad}Zx|dZCcJ87DGR)-ve=@dhj8q0wggs`Nv!c&59!uD`POCc_W_qKfD|`)Sh4tz z(n-^`o{tfOpqrQX=l0YSp&?0i$~roS4O9~G#ET`Dn`&pQ9QB#)-Kxwt!qKWDPWs21~EfG(1c3HT-N9dRj8JSesH@8(5 zze3%v?u38WO$OpzQ=_@$q(XKch@aUDw}#b_qRo*-gnIF-l!WSkp%vy`1(xeaT~wZ+ z{fz%kH<-P_FO&J_CH(P48fI~!#O%xkc<~`08kpN$i7LsIJoao#haU#1*MHkzeM39C z;A&z#)^)PSpP13Cgr1qtIMYYn^1Jdof25>axBA4WGZIGk4Qz&_j8ax|lOGxfAE6<=)HGI|A^ledPV#up4x|6 zeZ|4=Q^jbrm0F{!jlfWX5D0Qa1gpDk z23x}g?8(pK-UULo=sA9uT%l*pU|Dsly?2d@$z|M^VSq7+_GQtLZREwD**)hM%48*ZC**Q z(*RF_nhcM??X&e4I?W#3)SrfIW!$f1YDJmqmk}@q(j*|f7J>M2#~9cHgyR!jJdP)t zLWAInEU1ZM*ResY=W$R=zfsZ}GCNHkH!x@@8L3rxIYGJp(o~(M9=0ud z5gcq3P+eQ$clC8-f-W<~lnwn`-ops&tq3t!9Kk~)f`gqJ4MyFx4BA^8#{b-J0|utL z%p)MeY17u>e$4zw^g~;J?+QNKk0c9{BQ_S%#W|yvlB%=0g2a+S|5y;N+Q>=v`Ig z{9X~h>$v+dF?wcLiG)ZFyhDso?^@gcDiM`Cp_SmQ1-X#LXC=cs)(vzCNMi(i z`_0&7P=ta4!lUyba3jzop}X$MkJ{pmKI~`{9nCG(?_&Rg+j903hV{)nQ%-~sb(%k@ z2THk(p2Yoik5tsi*KxnkwJ|Ur>^!H42keDGVe(7KqU40vSFh3@|IdLZS$5|NrhCl+ zyxO1rKb?a6R;TlykO%r(@c%wG2b>NhCPOx?MXj%|E61_)S=PLTBcP^IAoNxs4$<%9 zcPylfw|liC{R0CF^Yc{q%ljxGd=^*#{rkk&*p=r1PtVi#+Y=rh zQkdt$muAoXPsGjz>ggpD+nrrql4=JhGp4_ zTisqAM*I7rTF>Bq$3r4;@7xbur#C;)vBky3bB%6=in-&NjGGY19?D+)(k=lhW-JaI(&QzZ9%bJ@rsdZhuPpFAV9{wfO zC2u)j4WGl%gn@4_Hbop^wzYFfci1AtO;)^ACcgW>a&mGW;ymHK|M`Q7??gfC8vd6P zl?~isrx41Y$u(Pu}9NaGrt+0dlc0N=+Lt=Y|bVUA{ zyZ2h82*s<9L2<_SzWACyYo~+va8gHuI#Q8`RN@Tg_OLik6WpUp18er;88D%gx3T`p6 z6heI>i31sV`7T(a+ka(r&P9y50^D;;W)&qlxkCQKX&(OMy$&2kG=E2m&}XVgVqrI* zXDUwkJ6_epj{d!f=JmIIxevC@QvH?v$Rty_ZYp+{Bnnb4?z*z`28Ut8aHVOLzGc0>?|8!33@DY~$nON74S* zfwIIOT0uhOSuO7l0N9#9E)atvbvic)9{)prSzq5~loB5qem8Qlxz%Vx?1L?q*Z%y8 z^xd(v166L9{J)_49hAb4k$KDDyH^e1(ih~uH(L$A!gAqcX8!9tx7oOvVL?n6M5?s! z*<6TMB=O5}QEY>Dp0={>(w>L(dWFdUwfh$Fv8=7_*6IGj+Un};#nI6KPiE+WC~-Vq zZEfv;tA>6_ESBJMzlo5WT~lAsq;>7hd9U>8XWTGg5x&gV^-bi0TBXFq=2h{7{~Qkr zjA;Ivo5-~p$xzeKxLXb+O42_(Jj{e#7DFpsieX*@uj+Z1M!9#cl5<#r!5>gVZ2(|j zC`D;Lt;x-`fHk;~Syi?i^=DqMv${6IdN1mJ{Zh-6x=D3vJCvHc*wgL7dbJSGu5-PQ zg#)a>v)M)}=Bg|*li1zgKH1WSVkvcU(^iOL&xAAC_Md{`~e0lX2o1{nY_{D)MW|>fGF1oq!XpVN8{V89=?Ls3=Fm&eGkj z$nHP{wZJ8x%%{5#T#3=rw@KrB0H%?^&y-fSHC0trjoj*Qj%1G9qvlWPSNx!$loqk{ z;ekhRoCjVTt*X(KCf*&DV=K?h{7&a=;FaXpHz*na_sLX?-;=+s_xBh%pC}`W&ZVO<9rK1)NMZ<+N0jK*~ z|E80LCD(Jt?Y1#Utr6YR-Tlg_A?5^;^0}g~zyAo$mhik-rsLTM$&2+kH8r&i2J-N3 zo>uhFh0rbUH@WmV_BEC2W_472deZrxQB z44cK$*43S~8EsvQ5~sp2dTsLn;~NI;3MMZxXMOb z-^&aJ@C5=|{{A!Ss{Q&%mFFr9^@|Lj)?`D#W%Z4Qh9AJDl9Ht(8R|ywM+Y#yD?8rn z>t~*Hgb>muW!_$IN?-ABO5bd2IDDUT_ze_>k0>%GHg@bvrDegf`O9#c=wL0-a4J8R zCtehc94)VOg))M+n1nH~u(0y;^WlZr{EJxZB>0zm8zREOi4Xo@c|66Ck+FDTih(Ux z<1kkP6o@y-9jFfYNPliaQflh%_80)n3kZDs?Hh&3W8P8NqSw;U^&9qZLR!G$!JEl) zXlmX(ce$pfp;6&mz|8U1{a;zYKz&dB66ES?=`Q191E_dZt;9LdX+Rfb=Ue*imkHgU z4*4IDmbhMQDuTKXyJ{GTu$l(FScZZR!Z7=mqW*=j^f0aQ7x=0lk(;&gj^ zg)&$M0R$~CCpSy1!;t{Ldhg=0=rLpLHYDWm`eNzs#*~LON;kE^e5gfmywW1r?bx$GT6y$cCKA{j)A^zC7Eh8WNulgw>wSS4ezD$2^r>gohN zO)PC}`~eh5sZ0E+Weol1yvnA)qhUjNcLZ(E>%tLBcRX6}Yrk4VwG8eIi7ff;me(hZ zSPv$xfWNih>^nKcTwjd%508wT@!PLPL(nf&3gK5g^kM)5vas|_-U_fU!$(fw3CJ7H;EdvVyy zXmi^D@J@?_O7qs|%GMt2J^*3tm7wIW?*$|!(~Y0$oA~5Im0D+r9xS)u5fJ1CmVYd# zup`D$6clSACn0eKY5`k2oj2wo&~G8TuIS{XJ?2(|7|EX(ywLAQ5e_?ZbY`3yKL&YDi)NWM$sT)|jEyGnb z1&vIpA#9DzsR4k;lZ|oFk$d?PZ$BCuQe!-Rh_*`?v>WdT#G%Ic^G|8X4mapU&(D{t zEops;F)>wU9hjTGY##SQEu)~&+h_UD1B$G5*9$4Y zpwt>+DkpWZPO4#{>pgBGI($az0@l^iS^;CWbK}szK?j^bT1%m2PcSx<-!dN^>EU7U zetR^V5cGfnH&QY8O!fACrOCd;qwck6Y2@}|er7d5!W0d*`K*`bsyzV8XrS~A>y#ok9iNPo6qR)3zu=A)&*5mxZ9JOfzs{HVT{_+}> zxg5^Z2F$y-#wyF@vZ>E zu3Fe{zeey33=9y_y_Sh2{`mN^KgV=ovDvG>zJB6knuO0!2v$(ZHeem@CNgj9%E}_5 z2FC^K9@nK&Q&S7d&vSJKsL#Kyy95*u!TB?&`$zEv6(P^P49d24@{Vt(XAJ$OV>REkI-!Nd6w5xff*sQ1*lbD5Zy&@%dIs~e;9q7go!r_v|^7NN_P+}P6B(Wt1uaQ*ra%?Tb9hI2cex{AJDX&M7De$)OyI+0fuosV{yY-)nD2 z9;AOa77cl`5E^APkuE6zQ7tU1PNHtnHhDW6Y6?kqWqB!*LaQJZ7CaoP!|ts8Zfe_| z?2}!B-L0LS9a`1Bi%?_~x&t%=Tg;S<426Mr4^kN}&)1^2ix7ZDl)l`0fsGNsdGL^F ztt${}!nbu6@`PL4Z5jcRvvCiKj-s!@NB}fI>rB6_Y&#S^F?)3@H9~XKrvVwi8U~ts zs`bB+xSgGyNLrE0*L*@`w*I@OPQLJm=1NL9w3y)G_peL%-M8Kf|C&wYHdY~&vUeCW zS&_V$7*@m?1}Iq{XsuXQ(*1ToY37o>!I|6&O==@&#}buV)aA^bRLU3Lluslx-r|hk z2@sSFX6yGx!!mF7Y$6!N68b-pS^WI@bIUNCCD(sjtEu|Sg79Ty_O~PpDRya2_ z-u8CLLCnFppoU7PZhx+mYky*Ax*%zGtW5NH?N+euMyDJ7E1b)?L&Te=ILC?bakt{_@1=#PR!-4aU3e1&|ELh5lt#SwCf7co7C52?5& zJ;~Jx-TcNPjRO1$v%fxB)N(uh!J2U(7yuP~>w#@LzKr|JdME{M7gJ```15DNLLu6z zuu#5GS6+Z7lAA|KS`~0xK%U`zRpyIq?0rdC(}Zm<>#f%rt2KlVo_)pYX3zZwaQtuoKt*p<;iQ-QWF(;gesJd( zl7b#|Pb4k<%&Ue2cw}Lr1WUXPUwB;_x7c_%iG&1*OthnShCuH&FZ0T;Nv=WfGD?7^_fj~rp1R6dS#vfkdHvutG zv#$(lf-bh>G^AX75r)#kO z|NH0M7`nPe>(uh}>C=u7>XKiVQv+KT(UQVn<^?yTYv=Y5W3trZdG%5RU*XW5>#RT| zz<141f{+Kxa@m!Rmx)v%y+;@rmjV4(oBnCF*`&aoT<@CRfq=$)4GKHkEiigLeB=BX zP)-i7mDSbTfV&1Q-3^PQMq^b?xr2_wiE-_&fTrFo!A$Z47Nwb)m^gj)cn}abPHh*~ z-?5{2>i_=z8%#iXc|un5@)nRIHn-xyKNvujcyynk+jQk4J%3D<>i72aU?0paV!Zfh zV`Jmt@#|x`H3r6u%ww#+2hToKFu9-aJNa`yrduEQ>wAX0*_6KP^V{%yAmbD*b-6WN zZa7zUxEjuL+IEcIo`}+-p35S^WCDA$IS;3c&mhLi%D8%Yb)EounFi`29tst>UG)}r z7)90r))Nx35E~OC(>?34JAHA&h5Gec$!kAw!1r0*oC6#uj_$d;v*SpHq=JG%W$Wq3 zXJDR(k1_;ohOdE0Gfl(^UZj=Va`zq+N}f}z zPwoAIWtGpBwYA4HZ_$NIH%Kp&f~VNBG+__OjY9tAx+bdR??_VT*8t-68=(~=lM_JD zD4Dn2f4+amg>qi`X7Z@~c3K(^Nxn}=?RCmbw;G*V4zbA_{QScTk$PAwD=Ram{*v@3 zW`Qcjx*(s)E4E^i7|!NcGwivT_TOkDd!$%%g^`J` z43nfU=}7&y$MXU0c#n-WP^ZgUkJeuH>I#sFaBy-G(Tly|5hDv2ZG`^gv*-cpz2;0% z7vu^_CYf=5d2$?7NR(bX!18`s!XIYfGA(!iM8ne!F+q*>m=YdeX7NTe% ze74n)ECbazElHtBA73gP=tiGF8rSqq!QI@CO8OlE!%pQnbD#F}YCp1gmKPWgH$1>B z*|_i}nFqqb$xXrfMb8CaRO`&-q!uP~Qrn5&D6%e^A@)sP|A(s)SpM6CWsMtf!Q zVg!vw!zbbs6Khs1ftCiOe;EwpnQbXu)mzj7ty7{IwNPA~u}6botNzSKCoPrz(`& zsw>(8JX2|kIwfl+=Y0Pfdy3wk4A;)E@iDy%5a)~laV-FKcV8eGy^rY!YS~QjB>Nwe z-p3AS+Q$Gh0S9M#&U4T}G`r+?tfrx30`MK+U2cG^dC2d$k2TYqx;rS$TGx^O@4JY){Y30Eb4Ym}NgQwcK9r3J3sxUWGjAe&x$dGki9ZdwLXwuj#}+BM$R3#8EA^ zXSpBCr>}na1cr|<1Ab@p3Zlfrk4B=Ab;kf*GrpHp);>Suzw8FO!v+kDsZc;K?&+OD zZCGU{tF29Ptd<$bDFH+}4lytQmOuhK@CXP5vQ?dA0+E3BxdQ}x>pPiHq88IqJPgX| zWC5G4@bDVb&!2YzcX^6h(kPB@Lvy#Cf4Y1=wR?i5p4oPf#}3|(W|US}YTNRj0CWyJ zsi(X9DBaeGeCU&GRdbB59prfd&WQd5lZx0}!C4eGH~DH!ZSBpD;CMGsB!Xm{=?tQ- zK@hLS(^M7d3e`j|^G)bNt)f%&zVJ%O!m$F-zrF}NXkKT53JR5qSH`bejKsva|GL(* zVdx}>!(VI!{`^UTYG!-6v%YRAOjYE*2mS`|OFCieeGTRp8c}LUo=gJc1AtjR}aI2p7TGmG+DG8aEsf8b@6wR<$YeNL)%MkMj z<2U#96{mlfw*W+C*c!YU{2)LS_%^bHrR?cOnLQkZ!OGs3-WxX{iDJwgpPN$_jo~oU zEw}=TIVB~9yZzc#xM<7E9SDK6w6t0obKG5SLyvD~fVgK|m8TJH1p;h?CTBnj7BFby zp3spG$mk5g$=BX)eL?zBNNjT7mGzfX2KaOi2rM*4Qp7wsT9tr!$sC;hTzDVIa=uQU z<_N!+lk3Fz?A3lTml9Z6_DLzFyv&VW@av3LHcvr z0e?T|qeR=-)HIJ62IgWMBpg26L}P#D!6rGVqDZ;Ju8G{qexKDJtS~8bq4bS1)y5bp zXjN#&sLO8|ks|gW_ztM05eJN->8Yz$VC^W z&|O5*qZ90~(>6KnXB6SZP2MxcUe#@yOrWdN{aWjxBmN=a6Yp^57d<%^SXBbu58%G} zm%wTpW444wp>XPw~ENuChK;(eR^j%U;7%a?$ zq!>S|Y`+De9$Z#5Bb(rozeY8N?|Dr4v5`wRx$Zw;l;)WM#XH@bJFaiPdBwvsGVv%m zIazljM;@h0fl5~+=Gr+uXkB^iiQdfI2+|YfT%b?*@k?1HI z?-aAnAUq(tNrMWgK3MMjsgjSzx(`Lf6t}lWXMGf<`R*sD^sYI%X5HQ0jkW$UymNva(@sOLudjiDH4x4A z8=07N2XI7AdTzV%t7y8f``*t9a3({tIDo0+)soc2G7!)l0#l^ebT8dcCy?3HogBDo z1BP?d99jK|xLWvfsadk6<5Op6s@|V^Vv6{P+>uJ96&N2?Hl; z{&VF%J?=n%|19speY^C{e0e`S;^|0${0M%qEBUnFXb?vi{|eAjmuXy5QW;OaYa-He z3XTIvLaQx$rO>1DfHDRAG-79}w77f&95OkXMKp;es`OoIMlPBxLvzA@ttXQEh8!4@ zC?#(K9XgM3DLi(uvhVT-z`m;pUk z-7K18STyn*TkEu@(Ycy5K3PdD-UG!VU@C@I^8zSBd`W((QP<^XpCwr8Y{9ABxZaWe z|6uK{gQ^VMwqGnH6_7@d?ohgsW-YoKq`OO6ML@c{I~NEn+64*%(%mUYcen0qJk8kGVFL8!d_jO;_c^=2_JQgOsh7@9j;XU#YMg&@bs_D=*1{nQBq-+F5OrXmq z8NWsE9kT91lo&vLM4!oD0Tpn<7cu&~yrL@qVe#v+X|R-J=|syP@0|N!lma#M9w@%g zncJ@UT_5qJ0=ra5>PDb=Z*$=Zsf8=lF^Is?kiQxqsr?b49X4-L7%Rcuc58Yl3Jy65 zxtW=nzZvg%2B@%JgVF_|d{p{lbDp1%CBoO@*c*~Wzd+W)mo^lEcP@?fDkx2qjLc}ABfdG2 zZG8)beV<*>W^?mNTJ9H1s*MGkSRZTa*$aN^z7yYNOoI9@EB_dXOJV#g;D|{e$NP>u zCl-f~T=Jz@K<2Y(t^fpT1)6}%>d&Pg*`E%ig~3u(eEXyW)FdhA{h&Wuj832^WkeXn z=Fu!foTI{-4`CE+DSC=)JL&?aqi%D%`?^mv|5A}0`Ixt1AR)R7dTYBHU z{z@f-T>wtq;S@}wP|~9H^mI~=7b7mf=D0t^LJ4`=$6QlW6AeECwP<5*?uTcJEgBWV zbQpqIf5z4`jH*ix^QWe!fW=VL`eM3WpRRM*8+bXVyn?5^uAsgHLH!|b=wQu}&1+*zag=JE&$A%>@-_rzK+C$f! z1P1PZONO;?0v^kmeDtjz0z&y#FooZdxZo$kSFhUru3cLau2&l79o>A<8K2lU_JhmU4baWVWTWc~W0a7IKEhENQ0X8;v;um1e%gau4;Io!h$rr}#gisV7gJR3mkC?~E8n~sSeMaDz0>vZDOf;L>1}V%BdfuFEpA7~A z%|neXE}Kyp9~V~~H##}TD8f;lxcCEf`J-iB+EgN;sDMCP1FE8O1*B}|)?(?5HN6wG zGD=Bf;6S_yA#=?2Q#uTGhCU-VDY-^E>fFOXc>Zjg%?sV) zf{w2rRH%9uCfRU!ijmLu5eYXjiXT2dfrQ{^LK2eRJ9BQ*?J)7l6s-H?_oTe{pK>Kg z?k{|O5(8@3-v1t{xcma;5m)er{Jszk$7&$GEJT@Fm~` z`RaZrprY^df=w2<&Uh8_GIdR_?cU|#OpQSKp7cMaJCd(k9u{#C3}W|8VjA( z%Y2N&BlpKut#r)T-r75{!p` zU#a4lCj~_hH%hlu+K!-ic0@-rL%lExfC_O3-qaQ`N{>b)$2yMRyGJIijsxFO&W)EC zOM<${h7mTJlQ?M2vmJ6sbU2zm#+xUdUnq;ox&X0*qVEHXCl5!SLlIL_JX%lGT`ZVe zj{>G8pK$pWO2eLq14`$Ic_Zzm##l__n()*#Jb>oaL+qlO~1==!*fpYd&_z6oA+s|Qz_dCsG>jViNQ7OV^t>Oo^>L3 z`lV3&Hp;D$khNcM{R!q1(O40b%vbod3iJtU!}9FSQv3oEUtYYRS9s?)8uN+dUSbp* zgAA#IOAGlBKH&|gOI&BX;D4CsZ1XCqV~Z?ibrldWr4n+-G0cW%^-L4X){cqhj4J4B zENCJgs{0Z2#b~ms;jW}~l0N9=kph=h3N8_xF{fc!pC3|mDcyJ$ZK^TmbG#BXg0Lb^ zWB->6h|p74mrR3}+NymDkBBI+xCOo5HZS>cVXRF5TjN66=$CmTlba#=?;sJ1dC}SO z)e=<5mXe4fKk6-kMxHs;<)9!&G=Js-NjIgx!7tffxBd&a2Nk8Qy?vqk{(W$1H!&HR zymAR$Ne3{8+910Ur}z|$HD*s8=zOT=9%{_^fg5k@GMMu>5|VRz%tipCT$DVXxsG)d zV{d-^;Wwpo)jhBkE9A9Dmqr`s4+AcRZrDsZm4Q=44nI9()T|KZ`2@T>@542ck>_mp z<~Jw)il-od$iK9qK?|nk>thPy*zUtG+j0WpMX)Vjd+cZ^FLtXCgK|p#@D_+rGB>)e zw~3qCzR^p%yu@3Vu3)s5`-|=7cgg*aW&fn;%5l$B z5ntY2qMMqM+`qsPe#P(n;e5JWvm)E?1fm?HHs7`U*WRapaIk2&_R>apUmE50#AkIr zk{py2Hhr1U8Pu_DH2?J$teF)WsB9t|BGcqx_21vaf1e{_%P^*`YImNRth~?5cxm!j zqP@j8&q+y-`BhBv80Ki}TTM}u0rd8VWC%OJgLo*NETJP(IX_UYUFDNCKP-{pw;FmW zxFBcp;hDR4TBP12QjBnDT$IsF`JILuieEnz`g>Fe!w_^KyZ(Vdsf0k#Tb+TZC*}w5BN##@^@ARw6E_C4K(p zH?P0LnA_~Tf?yZgw@?+0FQ=Qc3){7##o}`Y_<2m&oPULNFy6Ph8||;CO`i`Hjgz7f zi$ARMdRL_84Y)_u2(7F5q9AAF0_DW4UjzinAj&5Kf9|TL)o@S-D`)b%03pu(&lO|L zvuHoi&u`}CsG*=S4?P{)Cb|Y@;iSmr0$1kqBK4rWuV0UVIq0?^`7zvek20E6*(R3R zql2leL*$G>x=j34YW6Xv^15u#WJcmFqsF-Wb7|Lt6H2;aOwqPC->->K2qdtGkO;73 zzL$^<&>)c&Nr=PRwo~BkJRmbR#%?jC$v5wKaS~Ct~H!DfcI zwA*8n9c@vuFL=4Dy{7!@y@dHmcH7N8-m^12d`I9}dn9k(*MD}UbNKfcK?qBX3YC9K z_3M8gp9p2276s+-;Y!5Nv{EB@bKr;a`~Qc7Ce{OukBgt5pN>wdQMER6()sy0M(`@= zN4&152q;q2^bAYmZQyotD~z+0=65~Be2(q zdY}9Ood77ZM5J8e4!!{?TT)W;@?eoAGO6d?J7Ay#C8H6@#GuBo1r00E7Lg<-WIp)- z#4k*OCg8r0rTSei8p^x>gqb>1$kE0l{rB2e!LguS1v|MSSY{KYs);CN!tVi5F>()} zg_h%PvKa6oE-ekcdnbB#)CrcO`cgK)U62hP@R2r0@+3ircn#QM;Nx#8&0V1_p}b`W zRsmQ-+u(nF5CLHAo*f1Puo3hKKvHqqR7~Rx#z49)?2C}z5z`t!a5`b3+Jj>lhzg4z zA3aq9*8uFK0ic)B2r7EH1T+jDNsRD&ihUfEhggC^AT8ko)khNs_T1hC2KA$Ym)5)) z1Q<^=Etq`OIsXCrr$jNMA@E-SGchL$@#{!QB)Psq0kT*h3;*{Q@H-8`|4BCM<2F#G zfF}$6{CRJ={U5lJSSTMt{}cF%v+~pQ7#KXB;8r#SNEay7ShOm?^M3~GV(Tq#yaAX1KCoaL8g_7i3t$hfGQHnVGUm5 zD*#75=2t;7rjpbsLxmW`d3kxD$+#r$73C_wbDA6ZsOXP7 zOoEp%!-LPN2Q87T3o!~7>VFe%FF~p;}+ zoZK%U3;;PsFipV|sD%rz{cPZk0-^b26P$}kjVX=O;&(?d_(bFt6$gL);`i8@0EjfW z;+{as$`o)5q4zx-m91{sDF?OS9XJUbtgWw>0mKZ}F7jMExCWRX5r+{gUf7wB2toz$ z!~bpr{~dzc3!t&ZLQXB)#R6^{2H;YLg@u7~mTB-57_DDt?YSkBpp#=`ruBN;x@S88 zga9WAiHJ5U;rQwxzz4zI2&X+;F#daz0&E*!eSLj#adCC^aU{}%DI-rtM&=9X@c_`P z0=gKe)~q7XaipAxfr*Lv{CNpc?fgDi@XG+pD;OFY0w5}onUN6snQIClJi%c#v#{_V zXdm#1KqL1q7*)4Uvv~&4xOIyZL(i=dD%5~{2O}Mw_n>G-b~bSAZA7ui4!HRpoSaHz zU*O?c=j4fjvv8Yg4n4>3q<3e>)~8@QEG{lC?3=z5BI#nLsfpjGIw3xulZy-KuK7$W z<%lXCu7DLfjl?pR+OAJG$E)O8`Sww{A0YgJq;jF((=j6Ijl`0GV*&c12tqc_j6t{? zfMvoiUiu`8;<9L06+V{(OzWfP!f#vOu#pYsc>V%QZ`2Rjdd|sT9xe~RYjQ<;+eE-D zK>3g-<*;>gb2B!k)+dJ-23-9Oex4uO0VWT_)g~y5$-wxjs+rjua0gVhwPl+Rz%ng1 zkX40Rn~a~i2X!F5H-FH+Av>1ZDWLN)3#S|p+WDYkgyW-@LKI!%ETu`5^Hfx5bLm@0 ztqbX{KW@JF2>+7U2e=-<^i?-+khX*x1rtKvpMe{l`-RVhX^qP3RDPFLfMPpwrh$!0 z65Gop9YC!k_BLgV?b5Qc<09~ZiQE!0WCFwbTfGT@eVCYr7sF%S#k%w`7!vR46;fAb zwBWI?0`J}+UJkwn($U9%jBBH0ivQF`^4TDlBL`BgnMaI^#RD=J3o$ z%VU>iVkp>zBS>#FZVFCt5!_w!KGJ=75}f9K5(Uyl_$>gvNvBeTJo(tq(VpozV!y4L z9uh9ct?z@ej?+f~M*#*YfJ#w=K62VVRZfjR-sVe`<&fHyNcs*4#-BA9@KueZ{9Jiu zd}h6o=VyfK8zqfFOAqIiw_-mUuzLwZFGmXS;f!hHl0u$)xtTKOh%-RZe7V3*5BWqg zS+T8LPN43eT3jfi`2NMVu}@Ix0CGn}&dk8cMxH@>$hUM*ECkZI2BRF&s-<6y>nreB z34VD?XBQp~e?C6?*hCB7GiJ}kasc+H-gr8VEARyn~d}qLJ}CU)m(Gu@t-gmsp&bVg{VE&DEJ^9bP*jmQ1C;s3p3 zOQ4{=e{dunYJ^N3dG}sC^6|$t;rW2hw#PwsE4P1Me}0R$63oxc#sV3NY^e>W?{D@c zfY|h^s;QglN;|Y>JwW;Xt{Dt51Y=@8cs#WD?`j>7;t{b1@F7F7zUq8AG(h3_$*HMV zEZD)!H`S=+WhDj;6Q~=vP;ja)e)|hNr864a`$YHeB;+(WVN#y0fj!3CUmuF#-r`{i z&Xrk*7Ai0rJbFp|kQyhvV58C~i|NwEb~oEY-nhK}^@q0lM(d0L+j@;85x#jNy-91h zyxAnlY%gcGJ)0g3cU}Ag6>V5fBehso+rpqPZ>1k(_wP}J`P`>Td9^Jrn{vHISF=M7 zuQ(~(oW#t+=&0m=i!qfdS^0{h#hHATWz}Myrdu`~Cf97egrc)19o~vrQ%+v3lw=L= zm6spIr3P8yD|vh-DY-OHhJtRrz1}~uv7)qc*TF%q{8Ububf0eL&^v4C4M_peAHJ{yDaT%EW~E)E6} zy}7lekrA{sVZCGm5gI!sdCgueMd^ybP&7%J!df(&a89Kxjg|mJG5S;Dr@hj`ybsaW zKYiy9wg<&n=T~F(-|s#ee;ir%?|rlP^aBH2eU!m)rvBlcv*f!c5@wpCys%kG8WC!C zJ8>-o#z#k?S?PtttT5#vs8+89Ud^u|O;orALA`@q5Q=0~L7BN5Wa33#LD5cTGbE}i zPKA@rN|flS!%eMXdI-f21^hH_jzANPz=JQE)fGS@Y-k|GDt=a@fJ;t5PyskimZDLn zQ*BvU7|YDo!Jd7ZG&TQ!jWL1@*1d;T>|;fcQecDTd01Knt;t%AvlgaDX?vBg;-e!s=o`k z-!XrF#>5J7f>;V954a*41FL(bAfyMjFk; z?DB^GI?}}h?p709<|xi=s@CK;P%3Rk z3tZlcFv2mFYPRYT(gnC9EhHjGzckvJ>s5tg=h(TPd<+lgzMs#v<)%zLBd5c0`t?G3 zYB@%-(;uR5zNUOco}Ny}qSN`lHD~k5!p#LepBMG>FY^^5m6epWWSO?fQ^v>~xk>f6 zu$Rjmc2xbh((CF2#!t=(hGM>$ZB`onFsx_(MzatRPCw*ly0~X;S?n>tKpQ>$Ye*q1 zB3?di(%RZ#bf2{--n80br!#uGoxpuEW}h`)s;reTdY*3p9)|^MDX+EV+Z~PI5BQPp z_m^9APGE}iix=4E!3EX`U17x`h#(QMxR*zsKS^WZl3buLm_ z`Q`mk_-)b_%*PeBM!PIJRaGtj>uQo&udQKDGDQNUI`mHsc!<3EVad~&fyFjilpgNp z^fjfi_^Hd@Hy)NT3&X>D>p3&KWY&)K;WmUd)$`BJCAC~?t>+QjG zBXy({Fp2(Mw*T`7U71b&T%B-2FH)*D;41u;r&YnEf_*w7-)s%0LlYR32_I6y`T^d_ z$dop?@nO&5)h7)9o2qXoQ09qSSCtU@Vo56aKcRzJFcpcZg7!H-%m!0?KpQh9Ri!gl zC`XP&@n4x5C#R>QPJ6xa8pf9bOLl!;Aw4u@t-4;;_}+q|6YI%HIJ~yruCWENL93A$ z9Z_k$J8K>PlTP}4;N8VV_YQppl$=VPP8vc=YQT{m$53|FxvDsMZbW3b;Nkwwmqby4 zTD^NTa3`@6i;t-LOJN)yu2-ieXM@n(WTJVhGHuPQF7vAra<%v?f&LS&q&o-Od^e{i z;q<@iMTK-ux~*;B>Z^IvtW8}#^$tZN_dEq_iJ9a3G~HY`idb4Z-##8p`zsH1^>;D2mY!R+IMwXvIKFkdY>Ue_s;_!iC)Q7hn}knZ=5UCcC3T`x-yvC_?HfpFg)txF z8_23aZQnt%t$VIN<&?|!YpH57k+x?jO1*fUR?}O^h%#Km%1Z5Z?RG!UWHk58=G>c% z(UJV;QCoUaE`^!9;h#tIf(|HUUp=hjnE!6ijd7bG_mU|Ax{j;XtX34x;^QNE{#J<- z4%eE_uq^ylSZ=OaIK`6^POS-9*r>19aJ#3FuKl=k{=44Gne5lW%v<-7h}*zTY;$fM zRF|g>jharg<$7@?$=&M%%69Ad{$4NPQ%;K-2dx47kN(u{q==ar4BwM?K zh^ADD2PE3)Z9@_p@BtC(}cba=fJW$I-^%Kyf!(rj12JRWCS&grxSNM3$?;G!Y3wAyTYu-BqxoHA%zEAxvwzgSuxzOO`<#5`_5 z0Z$vqtIbCEj}WHj^c0C_v_(ck+_lGBpBc$%x}DZyFUY{j%6Zm%mCc#fYU|cKC|K-P zODpXiS;#7QEEdI=8|y2Ut_s&yiF@Ha+4`I`pGa7ESr6w<{mtzr@P*gD*ugW_Sqy*&Xf@aX-%+&_l{D#fe-@k$qNuL(HGT?h<)SBmapRm3dC`~VRY+&?~ zz(gKnD*5@OQon4+RcSC6Bi>NIH5+F!x{FGqhkUiYqEISy$X{mgd@{{yt7 zV|3Kp#4)fp27Rzfh;v2}5tl&6E|no&kFzh0=y)23w%=``3>To}A4?Nq6;s2Eac zG~cN#3>(6PXyTJJ(pB!G{?ivT_>wP(-DTt{4l!k-bcPr<=Dk~Mwk$*-Ja@bCd>*A{ z>RG=)kna=8T38OpswKbiZW*JTfV*|h4X)S29Fn7>Jtg;}vB~-(7aqCtta}B-=gl6Y zqFZcaa??%A%Wms!a=OUcT^B3*DlF7mSajXM?RnMZU%*SMkOL-QgRZ{XV=8K}5^hK(s7X_TxX7_19pRj@GH~dAoKA+~O zFFvV=@9a+SLQ19g@CMu560Q>_??J^_RL!=~>M zXhdat-tETWSYCZG71JU|k%K>&qo$>~?-OF~yQU;+AJV5O(!oTIy{Vj0m#XlWkeBvY zR~Nr?z!zFyjOp{EftFdfi#(QZyU!q_&$FPRB~0j^1-d`h<|*Uw{iW@rIX&h+Jz)o9 zk-^d)!X0Z^)tDQf`KXIuF$HpCQPJ6F=Fr@8N5oHzY5X`Ot8FS|H0D%itlQc-H=x#F zp;fBJ=|OyIu3z%_yO=|6ryjhE6LZmU6OMYI{`S1P%3GHd+OVG&lOW8-FsS&x*mTXl zD$x!$ow@7p`g*!btc4?@(ZgNmY3d{+uC4x+2rq=qYfhcY7u{(bj^WJ?b=nBk|N1!uVM2yPb^< z?$9z}c!0Z@bepo+JyJ6QCysk-Rn-B~DF<+5>74Q<9E{m(waX8G*pS_lQKk*KN##|vkH!u(4Ks3`gtsyQYosGuTvDd-+$6| zG&M1LxSM-SKheeu57mgYov7E#H?W$3o_`!*rK6M3EL@9x0~%*K@bzf0X_xw+C)R(Z z=rGx$5tp0|>Gn*upcj>3HjS=$(&Z{J{j4z^%km$onBk=0Mzpyit#gxj~tNG^Qd2>XOLm zo#|+=rKkKaSPHIJp{+j#dESx3we`m>aN!C4QrMyfjuyPzq-SYRI_bAAlG9A_@z(X9 zNIL|x@(MP2@ke_;iM=#+y__R7iwIN2Ob_VpqV5(`iu+n<#A8g5m6TAZZ@jn$?+xoc zZFX}lo7&1GLG{|dlXl^z3F8>B^O|a`dr(W}F$tR;b;%or9EZC~PB&K?P(-eV4=c`f zKWP8?`sT>9j(A63Vf*CZ1>0g9ggQ>=XQ1l5kl#+q&{EQPne})7A3`E@+&%{_+M7P! z<%;cf*6Q{De)wKF=zLgt`y&SW_RNHcovc6@hk}Cr>=Czu4@prGDLo=`jF*Jo-}l*K z{N8-yaP{`^sS3-cy2?`t7pcdu&IK2Y9+)0}RWTF(#B62|`oOco`K>W?LHjpD3+nLL z<6!PXwlK6X+Es%YJfmR^4qAyGaB+hL(}#l;>Gd_LyViCdk@Rh;F#C8Idoik^d5@Hi z`-qsb;mLnKFsYQ`yBD3=zdJrrp(hlg!;4d(+LVawvOeP|a6jM4m&bY)6UjQrS!$Nheepgno zXikwnArDgGv3=RV;Opz}k-(!wkf#7q(}0UCZ}t7J7I2btT{Z5K);#Jm#D5=o;#-)( zk=1r}_WOLW8Ihtdh6ywFt*C;|k8CXeE;`6Ie_xx}?B*Vl;`5wxX3-TVtgB69wpBFc zZrpECnAZ%^0M*~WCqJ>q;bXH2Ee#mrrylq zw^OA_u)siG#m_ufJ zCwKex_v6Dbq}>ylMIkWvG?=nttV-Fh`d-MOP}UDZqCrFFB3S+F8VPcS0*uhAC3COw zJ+FzU_z+v~u4lIAp3_gy1se-w_}g3Lej1yM*M}pfzf}Y!x*3+J9EXUh#)Rty7>YAS zuXA8G!Wi+^4OWLIElHCI?c#e;Q6BOYZ zOkG?5gGcu4y_EFuBGxQs546|wyif$;}DA4<%-7f)G=Q&T5k@Q zhNyOI*WH2wV3&s))Ks`Kvg1?%5C@oH-bR&|-6&7J*X!on-r$?J?od~at||If>ahMG zUPME+@J!NUNfCH7d2{dfmnpUOT^=llHy+gg3Z` zJI}K8X{prQqhh=LEH_&Ve&2-h9kBjpQOeft+Hd>mvnT&|@BKgy!Cu1i`DVN2cWm>? zVs&P(l`{UkFe%Qo{p{+ZULp4;s^a;S-J-|e_v|M%OK}S|`WG{-t23-s39kgzMorB* zrKgW@&O#L_V38^oR$bFh?s~t)jfD>Fqon0qeMkt7Lt{-7xN5Bm2cja>EA^XeddOT3 zV7TLn<%yMhtT%W4mIGmxnbRg;up{>GlAHSAsq-2&PLnpm=jRsFm zn(uFpZZ;N{`W?dfJ+wR<^eC7$HwWY$eY#72P_zs`wCpZdOy5Cm&7-|2n;lhi#H_d9 zY7Q1uKrM)ZNJ*Dr}H}KK_I=ry>td?51!(q!&sWSVDbQQ*#0m3 z!5QB7rpl-G5LeyPb=dU+}!&<2RD~9JyN%QqE!e+fOwkPj6aV z`*Z;kc1Mfr3OVEv^ZK^1x@D_Z`9<5g!p!y@@yb^yq14J1;j_iUJ%`EtK|&e6puOu^4|Oy&qtoNe8a7?&yOH(~`=86#`b6;0-t&y+ zXIAD+A~%%epXyJO7RRRMR1jus-L4|{bn<;CGZ_w{MX)lxx`6v+!T>YIiBTgT!5VJO z-K%WpCUHoYAvpai4qOy|EomVFuKN^)$fC3y?PU{c;@ZCP3M2f;mkVI?MdTgNIU4EU zLcEpp10Kx-jCJQ*pQc_o8pH}Le8gNEV)J7VCl5IpBz1hDTAG#L6Vxa@P> zyA$UBZ9Kjyk-v&t-q)glL-q)0{dieP6;f84g-mw~Q6bBXrbqb_v9V<{ax(qOBpXY< zhvdxwG_s?LlM6VGF#d`e70suHzLl)+i2nS!6$(NjTR81WY3{Sno@OrsVQP<;qrPC) zu!f6u_S)LIO65Ka^4z@<6Fvc0lE_I#(ZuS4>f%U+I!iCcIVezXaE`wKl2epfpPTK(v zZ^*4TmDuY@{kFTZtm?w>?@+J}H>I(kda6gn%^T!t;2sr_L8`D*vWl?w1@+-EWppP- zr-UAhR$OFr&1}CfqrF5uoF{p@4S$r!Vi{4}gL~dy13ysLzGBLuf8O!;&AG{4E*8Q# zgRr!fp|HvgrJ0Jhw&@L~J~On`Wzj8qza?JHF&D#IPid-INiy`^{+(GP>HPIeTFqbI z4uU)r#ILCHg3y?c||N)7Vk{>1*1wFQb>kf3Tp)km6`jv9j&~ z?A?^c*uY@H`MvtZ!J-{+hK&jFTaNnrde*m3yeQ$^w)(*s`g)b}?;|1!S{}h0wD|Py zY*XCUg3xIs3X3jDhZXSJSDM?u9Zi^#P~0G2FlppM1;ep-Y=5YcKKA1I0}C}R!p3h? z^u{NYmz)wY=L@sNA}Lbbs#!ygF#}Q2+0d>9i}1*K;ub<wI_5m3Hg54IxO{CVT?HAwWu#8ru2te)aiLSb!F>z13U zVWs$Qo2``LP@wUJ?rbRuEqukBb#YHAn{!x8?=z)a$PLUJwGoKEbZ49z;>bS;P})m= zcIZ^y)T*}d8&RP!XMI;nhjtQrQBt{`9O{kpl{$&$=?B~R~=EGoMa`*U+(GoiiB zUOmh$ESvhbmLkpcWGr(J9bUt3L(&nQT$zv2lEUS3V}2L}Q;St;Gny;agN}50deX6U zD$#8@7uRK0p!bD;^ykhKeOwtqW{>DxBlB;$^~CfH$4L1QAI*Z3IX*pgE%uOptZJ??2U@Xa%ml{Ai92`uQdI@@_8G5zT&HR$F~{;-m~r!e zT}AeQ=Z=%NP-`6>|KV->m3OP`GeJo{b5@Pfw6=Ivt0-l}+K^8zuZ_Rpc9`8rqH}={ zm$#*nk<6Wx$zWI9F&ELsX^@>NkG-r{f^FO)i97GXnJtHx#OpM>T4_BOm^M0G!`NIW(=0_yMAW-3 z9z)JGW>u0{;T8Xnu$&rQJmzqx zbE-kNBU<7NuC&z|d8`Oug`L$=Kv6XAhli2&bzO*d-Z9CeR$;;s= zBMDum*U0b{H8lxI|E*xGPmuq_P>GA|Jzfi#lAm(IVKYiC)39JuwRn>;+gG@lWv55h z=)i2VBRfB$*4mu=g)J?GI;CX5IE!=Hl6Ssntg1g>p+#}G(I=X4qQ!2+iYcj9#d2)t z<{%&j&m>9Ip&?$Zx2~;kb99guTYs7$EM*{rN_%)vd)Pv&jwjz2ciZ`TYS3Vr3F&p5 za260q9ERf72wV?aT&BuTe|?I3?4~8mH{Rstrs`dxF4-e|Hx!YtWjdV)@AO7C7@ z%BFD!O84Dm-xj$5@k=5lWA$opmdkw6DY9o4=rB++&C|8QoxQz-C5w=E`@*iIo)Wal zzgo0EiyBK;-Ityb<4VyU%sE8*HaKpda$Ed0HPwfQA1ar4sDu=}x_j<4EUx}DPU2FG z{-*d?&#Q!bY2ms<$gp;H|LPDQozF&Nf%4cz;FL2x^9Cb-jh#$8UC(X9yhKVq=|8r+ z(Qrc=X@xv@dVo7oAGu?x8V4j!+Ijjluj7$NHAx7#`YYvaZ6LtRa;y*ngTb(J^-*GU z@%BE(+Hp@f`n%fr>uLF@WlFFg?hJO=P9!UNA;6=kj!rHSPKkllJ{Eb_W`EQnVVZZ3ZVtG5Y-O z(&qxMijXw95+Z&2YWCeN?fPo+hMJK$3(SpBE@f_nYa98S=_^t6{1f2Q>N zyy`{^Svc4x8(PHV$8`+VexK^Tr(fJCi3-Uap#7V*x%<53#9G9>*mzXeYsmmoy?!rZ*U9Frdrg?QWHB{j@?$|ENAuFA`XZt1vFj$4tnC9W0*}YVF zRkU<7zs_$anNhx3!l?9!&!e;W=)PxnHa4)CEAuYPFltdI0SG}?;Hu>IspD%nd<=Dp zhxjJYl$YFbWJ?3Hc}d^Rbs~!6+Vz)pQvl1u4;3IrLJp=ygY&5lfNAG|KO@4FqWPO| zyVCa__^2_MJO_S0>l;5{EMfT@mAY9>n;|1Q`uolGG!VUSA?eb^<)7Bc$UdFTG%|7y zNL5n)uNL4i>vqOIL(0cysPFRe^yOo+UU-*Xa%oY(^U{Z}Cx)^`c72tpkW-74(GPbP z=~4_hSGx-i_W{U?oNGZca*2sQWtvV-PHsUl4+06Y>2v*iE$iMak3|2OzGWed0Q~T} zaNwLICnskcARo#JYfl+LplQDhe~vZT+91!e5xi zL46!2kwx#$rW5rd4&_sm(cd6!K%%8!uUAh+X(Rnr7@RT>dy5-2D^WzEgr073x?mF6gs z+vh%nxg%u*aufcO@1}DalE)O&=@U^=KFLl8w=M>fdO6PN?cU~sWZsn^Kx|G-Pa{*# z=;-KxL2QPz;0W^l0P!3Bgjxelmb!J(-nQ|C&!Jl+BU?9u9}UM~Pb;BpSLl1;{KeUL z#%KzlYptl`tN|kp*vBxpKrZ!Sh312n-EU&Y|IH@g5#dAeq5AY-4ot6Os_?Ur0&Xzm zu@4Ek+Lpyc!V=Kq0_5@zK%_*fpvTU0vAZKM1wWPrFv&DM*k2Iq3T()&B9XzI4Nu^1 zZ@aggs*p=8XCs0`LT>&}J!dM%2{`Fxh!%TPmZF-;i2)uQGqp z4{#m9kCQ#`Jouid3EOk;)-i&RjO1iO!rcGicW;hBP#oY%!DwNaxC-gcix3XV|Nhwr zQGnB00^tH_%u3|F!|?<8i8>$t=UbGv<^d1Q!pvL+Tn{XH;?E%Wg@!QqE8l+t#IODU z=^Huz2$CfGD1RZ-4_V)uyp%xUXW$g2QKzdTgBMN0$fJGfRD07P7?u-BntZw;U9ao? zNe@`4qa(w^lly6@-4Yt6Mt*!}bJ5V#iqG`zWKL(@JkX>qqLYOvMggj6pT;ck@rUm& z0C-2<8y}xi%(Mso10U!hr8Sa9Wqk{%{SQHMwAv*W-NET}Z08)4o{it>Tu20Txe6O( z%rxuO>-_l1qFJcp8BH~hcdqz@<7?l2b}p%JE2a22LQ|uVlw215wJ+)%Hn}((qh>m^ z=T0&{U%`X}GJ{SBO>2OYEd(fGKvrfAT7tM@km8Nx8&Fo>IaNm-Jn7s!NZe=Ykq!|NrrDbMKKn-25{X zcAW4}U{oY5CI)0vV14RDE+Ay68~SKfVC5koJasfRkr6T=g~spX z4+QliNZFnfz(K_Wi{076$%%1!PGv~u8)h4I+|FKQlS*Ax={rfDj(35xY>EW>8O+F7 zsDkNTBs7}@1=)U`lp{}$&htOwpmo)pPF2dKycr)VNpW)AImn`NoinRQ8HnXv8~Rkj z$LD_eib{*tVo)I>Cb{2S?Es%PW7eE|%hMVPA6gXrLOq@=!Y9T)0hp@ox$pzaOh(&{ z7s>Jp#=_D`Dx~Yq%{-9~_oU(Z3t)J>0UsC}Q%3 z8h}X&ld8~Q33lxIv?$b|CBS1s#R@7|Ya8 zhffOCBWzg!paf_mGV-0jno&h8DRz4MLlL++aal<}3G55u4yl8-wtN#QHc)20#j~T) z9#gq^La{~_@*m$oz8b>SF5z?Q5$m3PJI`1+ZagU)rl68CACM_oZ$TEqGV{TrCMCDb6%ps!L!(k{Z$$|m?U zV-m4);~<~C@Y_KQs(-iON6<*bUV>0zXALHry2)R+tC;UP#+>?7GP0RxzdijctAeB_7>P%so-t-@~wii?zA?AK{6h7|4A`+N0_ZEAT82n77Fb+lQm zR;|{4A>B=1#K0iU^k*T`=3idSBY)C97N39*Po1QNkB-%u(o2;hN;vXrIkQr@8A0Fu zjb52R+}H&EkNa#+X0=qHLffj3q@BT<#`Q{Uz!xLA?T;|bd~TITeq!jb#Ei=Cn%{TH zK`J~=S-8vpIBVWKh}%UO;q|LZIsCsgn+PGV=g0#^9uoXY$+gdMtr7NVxpPCagE;t31kkaIXqo|?A-bjen8 zthj!c1uMHVotjNZcgW&vJRbQz?~8p;L2G7N#=${W;j9-Knwe zeV)8%M6n&F&>;`~8jgoDb#&iAHr1)OYhXjU9BTrkiA?E`>=f=44lp->nkv2jaDo0J z;a8#y=fQYVk}8q~u4dcY41d3RTM{pN7p`JyJ3%7I*jH>}RZ@}P^2l6X-9x%8Ib&jJ zNoUbqvy8^PypRzh8Pu=$WgWtNK-M*3^(R^b z$Vo;)yG^D+#T7b~@joqD4TOc1M6662ev>HLg(8We=!6;Sgq-*6F)T94_)Qes#UbZ+ z!c~hl<0-0kjkhNSRhBgxJbWDUBUTS8?T(9Ft7aVlo8(T!C#~w1t)Io@w&>am7_33r zO;Iw&jUnA{uMJ7~_&9ow&MY^NzngQ`^!t$nmi}v||tE*a~+T`66fo>~dhXuLw0fo(=NBLC|Su`2~-UCauZt^xBBJF`)^y>pT zu=o&Wu1%|LKfmgQIsota)wbMLAF$b1&WzNd3O#O8R!<+h?7g2W&qt%0NiUDk%C3m= zXwMKCdCDK79MoNoy~}IYdcpe!u~2($Yx7?;%}De|K=qfB=Bwi}{QmquxC3*x@5%*~ z*;aDQdC~?p%YEv6LNtn@#ZohFbU$4^yeRAoiC%CmU*Eb=kbJIl zCP9hW(MVL@+1+I$ylg#@CNh+oB%L8&r zk@*22@LqhSysFCbf$dMPn)PT}QI-hOXc0T__@+YsDm*LLa*K(bw1ZtnQ9;4th)Ruj z=adi2B1cp~&}sGtqZ;igc~(YwLz0ipglsq6sXux;oOG~Ry=O1E_#_`D$bzX^Y{4K6 zzRQ?YduYYd%8qHa)MY0!zo6bPp*T(`LN`0JEd0zui@HprW4-QKLa$v<2wpg10g`ID z81k@$;%;xhUY{=+KGUQR5-)G>{eAZsAfhNLAdMj1-Jx`MNDK(l-AEdAcbCKfLkz;uDJ?m4 zhk%5%baTG5_xYV#>%2N|&Wrzk!QRWYHfx-DX6F0c_jP?fGtSaV0*~?ZsyAyPGWmlC z_3CGJlw@beFkIR5su#r|IxER#qkALz6gA&pY4M~wU7{u~s-6ED>EExcJ|w26Tf9}b z^I8+yaeO7CPWD@rf9;}3N;GIrP&6y|Fud$Q4n}6z_QUW8;5Xn>CnhHobPJ;ZO`SQP zSnGa2?>e341BAm1cW}3D^If%)&*OmmgXrFWW&wGv@AzPJds`3QsGvn#|Tn_fb9QP}22|w5c~k3skUj z9uDd)e!us2wxzT*!i|7o6&#EuB_xIzh7Lwk4LTZ3-qS4@g1RMcIO~^IDZvHm_Io>5 zV2$wpRi4_I&2B1{k4My6y<~&qpWGIm3hz}KTV$~ZQ=pV@vMhXR^@cGb60vTg{`O}H zBfaIm8(&kC=XDtwq{7?dOBXe_8v2__xpGcQ9@$lE$~??*O@cxPQro@-EyLj-(5c`; zODsdRz<1Ak&^6O~epO8~hsbF;Qj5pI`(4v{8dUY>J2LPHp>DeO9H~SN&3I16zxYaz zn)x1z*0oZL>pWJ(fSbOgh?AGR)(`iMk$5PLsc%TXldL@ zYadTh(A1kFAsGV6{8~hARlOW?K3cN7=L)v__^JM(psZAoDuWx5H@(CKxLQVJZrIRB zRX0|C8+dp>cZU^~LW?E?f_EYW&)M)8v?b*+tR;m8y0Vm^GE8gDYLq$SSRc*u znmAdSxF*nz0wW>zaSWI)FjvejEGVf)$Bv`AsHdY`8k!BjdqmIwc=-*w-!dqw=~tNa zfL<=}q`alCsjhZgX!Jle`)6J;p98oj9ca%;kH(@1HqiUY>FMBjcY6i^Dv#!sWMtmA zlQGjmxr=DkPjVe(ywD}}0WX$MZNL48%CqE?Ai!pe<5+)s?-hwYnz;+wa?sKjktg6X znxW67l=U9;h9mB%C*=178Sc9oK~G-FZ7ul+lUzBp4Z_$VcYn;0z$=E{>E`SdXT9-^ z;PGn+#F|`&P8bvl$iTk2)%!hezLcPkdU!x#~g=adp}h*>r{ z7Gg4dwHmJVp%|t;QtnO=zN0{0z#Sc?L);QcSsst%n>cYJhZ`XDW@ee1tV!Gu<19A5 zs-iD*4eJd%&8#@;`#TpFRLa}0Lxdz#j2rM*ZJ3+t()ywU^-+P2i*D z61F{4V2fcJrDT5=z++LY#}PlA9iv*#p<0}st64m1Zbnc4tcbE|e(@P)ubI&PUM!xb{nJqL@ z0V`+SBxV@%s0>I%6Bvf!3ZqZ}^2 zvh1I3Xv0)io6dAIyHjLe*AwSZ!oC_xh4uU%O|?X=~w4(c@KA=KNdn$c~4 zRW)eZ^Jua#-OQe+YQ)hQQoNU&EpL1t$5iLXSgMu4irjZDc5|oyP({$BtbB;4L|0v3 zEIGSl=KR22EZ`T?BZzMAjeHz@&}F%i2x?XtzDaJsiuwE_czzaK|53nk5NUK-|Cv9hp`NESkROb{_zBOEhywBMDK0AY2 zJfOtg8hxRQzMIV?{7F&ZQ*l$(!W1CtPNkcMA#xfT1eOHmws7D~ySwX%q@mjL;uU`w zHa2rJZ(cx(6n#RIIpcHVFRavU@E7ka3Fj5&eN-!1&37L`^c>J1@0q)WdN(}&j9+4n zU0)wxp89xA}3u7q0TU15u@3gJ{$}`D%r+2tnWLL-J32jS=(?&RedIsp8c(7Nw1nv zKb$o_-MNq!t+8^at-{ZRMUm2JbWHBqx-~Q~c5ly@t)K9Tf70q$d472et8~TtU23Ns zT;+~=8Y&j>%Yt{aNDq;_B38F$%jh<=RIq#T&A=W0!-7}cF_zvm+c8Dw?{S(nbB;`% z*fXeF@p!p#v;D;-|7O+fN6zmd*E6UWu%as7(cCI{sE-cqu{bb$<<0DYq5mJ89}W!) zxEN2`mBJtMfVoR#aAaZ+>`pDhJS$^)YWv)qsIod9&vuB9_f7r9xr?AYr~7k)@kvUJ z>FM%gVq$N*0(UN(t8sDS3`0W#zCOEC?l0-q`V|YU-NRFdMs}1TVyzi#U3i!~K8=*O zANPi5h5FwWML&FtC|eVH`Cxt3!E(r~WTw&1y6Ujd8xD!RXdt*Ay=L&$e}u%we{URW zQO86rh{%y$$?x`cKYZ?*5jM9~>K-mm_gtF6c-(S&n!XoR$UN6MzPA}&8TMg{H?>Jf zE+H`?gNzniGareB+3$EYxM3rVN0X8^yvf%Fkfm}##%C<13W3chuP7b{x~;YuJes}s zoLF#exG4>$_4Q%cAzgd2`QxpC z8zty4L)|H9O00i!>f$CQyk(B#lT^{6eQ{_*BwZzO1gX!UHl5w5@1j@poJdERY7jKH zJN%-BGBdHgMHxD8yzH#xKYLRovF;YWJNouq;%BXhWgM^FMMs57R8Ks$N+l}6l7rEquph)H%TZ@pCmw(_}cprdZR56)Y zS+fAlMa9MD(Mv524ctd6cP9HRq^)%xPL@QftpD!F5)>@)I21WKU(XA(9npUj3JQ14K_-RTOO9i9*tk^8Hn^0Mes41^~;`0{an7nG4#O^`R+(l_QH6>b+h=JGmPS9C1sv z{GXVxU-a}92h-#~-20%k_ZrPj+*LLpMlg*}uv;a}V@A z)jxrq#EHVKagS_}l|$=~IQB^}8pICFA5>7QtzLf}_p)U_X+87ZP!oEGlO{=xQdfR6 zr`_qabrZ-2uYdW=`f791_$UpkIs21a8d`LeDZCekM{l`lLEXuRXlPa!OqHwIVgKtl zWL^yM6FoJP4Dn)dNRR$Fo0fV(WTngy_qQRZDvF)pLVC=#hqg0bo8qzIeSc6@jh0Tc|+i&SQ%75d-ljIKG?XWG3H(@8Cdp4zsZzcEoEL zDx^xV9-d_9FfShT`20j(y(*IYJ3BoifEqlNHe5uSih^6hn?sKvT*i@egk-UN5w`e# zD`3lbU!LxXx@}K^;X%i%&kCrmSm7IzNe z(pU*NUsDyWiIm%9=Hm4mvjZfWJ`_XtLz45UroqM1~U6A!46E-y@ zh@=AHHU2f%oK;WAe5PYpGIAg}>%}CuZ|3O^RcbPojVg;V@q?y$#?Wx&^Cv#ZdKUs* zI1~l%twyXs)HxQ4)YBwM6X6v3D)?G$y)W2F-?BP&R`qv^hX>(b2=O}-LQ!X<8}HrZ zy9rTlwFWC&TcN=@YmNIv^uAX4IZ@uf*9&3=n?CbMTeu8<*RCa|` zciT-E;b2h3cRD_B+Q3o!(1O?o@1f&3azPWiNx}$CZQU6*4QcrE0M;$9Xog2v-HYkrF24ynd+ ztZa%SGLSNYSx|{O?z(03$$w@6QiU%|eC^D(1|x_WJlz$C;f(aQ8Uqn=gFk!Vc1L3k z3ewiH!)6{LRaMIs2ZsF>DT<_&sqClGiiXujJ|Tw8HeOz?!=C>{cT9V)@aPXy#%&^^ z-6q*1ym;(kCnNHKd{%319`smsLk}AjxZOLQg=sg4FvSzOKDk!v80uEWteM#tv*`A< zeLSFY{=bqA;QerMeQW2)ESNb?+bc^2&>K%-<(!IN`#yQsn zg(dd1hG}dYfS8gZD712liQ4^VcD?4xhGzT3I|E~-)Qmb42u;FyIBAXy;bIsKDb~;t ziydEJ#;;&1r<)2c>y>InKj##UD2hAv=Jum|b9sNWA zd#l%bd#iKgyDKE-V^1TY)A5}5@myvW2EuO3tfsx~=o4739I9LLYT(*Nud^y>=d*gV zdqljxMvP2|YO~A^E?9H#uL|L<58)BOTRaQCV{y-TD+szO= z3r&I)6iX=10!{lyD;fZc$D$Yhc zhrz>N1K*09SWj24Qc(U(`#>9%88229|IOau9qigzTESSROaA08OK4&S9L#+rQd9n5 z?a;lr%0aV7hE)03lUI_`Q;u5IB{*Gc5u~}SLZQ08KiOn0{D<zKCfq>3kHgrOYiWGHYDOWs`hT+2Q_gnL3uPTS5<5F;$lbl!St=zVHYit=y zZJiIz_+8uWxvR#sx&OFm>ei^A$VW|YZJlaNPG0bB6E9xveo9LBvC)i?VOSgeHc)H6 z6*$oB{#lkBjtWGLR*Z}f&xufY6ZLa#mFo4)=ZmyxckC46!>=wiW@fEpL6E83-nuk0=jI$yN%(S`ExC>!Kh6m-!A5-JvW+m6oF$1o!=( zMJ`DHljC?b1rB1SMR}ymKBpaCWcbu6#K!+5f|i+N!T%OzB?q=M!C_$^*xJzdx&1*v z0cX2I&C9wok#Znlw<~t!*WK(p&!V}0)`ssVL4o1;G&iqdRlooMlvDoaRVVcTeDhGj(`o*jP^qBb_ ztVx`^r~uLD++O0&Hu8^c!h1h6`RNfbb74nLNP1YpT> zG+?ktWr-Yaz}Ih1Rn;-jvpxJ3$#^dcz!>ged7-F;Xg@s0L92aw8m0y#2*&{g?$@X| zj8aF8>R;I&OG3+0Tw?%lL@^P!-7Z0#4)4VaPGHl(c>QJA!sHIaR5t~#EN*$xM_2E3 zF+x1%D4gBOiI?M(L;?i={PyT?3bpo&&A)&D21WYYtEZpu+*C~4fDx$uD_qGg^Ztyq z(!>Ur3u{!E1_8iU;Kg_U@{G!Y*`H#?ZvX}51W~K*&dyuOzNH)uFaC>4o=lpkGIJH7E45yAJa6Ued*JoD|Ex$F((&Q-gw6tpOr3&g zt@D}!Pg@g^lrp_bQOE}@jAD%<@Zv|evgHG^N)zG@Zg@toL=gh9EH+R-fKKf83LEu% zh(pz0Uyw+yuP)X)<|-8s*R66h#GuC0UuFhRP)I!BfZ+x_#D5Tz4tPJP=g^99LjP~M z5a(TTDRA1xXEp7r;D9U|sc<>2z1T97=5*F)^0K5yIfh+* zx)-Xam+?|7FZsMf9g!p95NM3_AhYk>z##qJSr^ z3YzGQygcvpC+JY2h?Ilfhl%z!`y)${bXJ3@<6PzCHmkj*QaWl{Zc=I`V)(5a*p{|q zBQ#s2Z6H&oqhrYsAf$%>tk%(2sgjEF({+tvGlr<*VbzGSjS2 z^Y?#FysJD)**x)OVP<}#<_T7lV4=65TRbR$4r$hTk6ooYPbPk!u-9#F zZu8J25zH$6hp1$GZ4eGGm7OgcU$xydAc_PKp}15n66(8{7-C{1br8&1|dFJExIxX3A!n*ivDb;d3h)b4-fy{csdSCgPS(oy2G6R zEe2u@gV^k`5$PVC1j9W-R-Kk~rQ*sj?@Fcp6@&EAg{d=kU<=>NdI#6)xlRts*!wC= zrAo#8GwqX|p3Lg7)dj0;lkLt0>3Vg!h4D-q-eEu=e}li2jOp;^wEQxpnx%$Gl`~2B zt?ZPgZi-q)6_tqZ`bAY5B(7wXX2+8~L?53$8oG-A{%^&!W1E77G$(tA0-^LROud3b zZnA8WkJT&NPtHUNc_GEXWNV zkGRTHEvnp3Kia_5>AfO>Y{^&Q|97U!Bl4814rdR2LTKJM^J_maEz~xPQ)GyP)k;kL z9y8wU_0x*u7QI2j}P60|v7B3~;c1}V6&^Qa@ zkvS5Pn&hoMx!%fSj1NJ|1(U{ z(A&J8=#5!ZWC+SmkIo3pY?&Y}*@8Erxf}=hNX99c3zfyAK(M2$(&#XOJYKW=}`;YGn-p`>c1 zTBB_!zAX??f;}NW_{Igft*LX#M{Ej_$sjEGIF1_VvcNhA=WaG11817`^~}F8l=LkN z=EXeK(iHNS49bHV3EYkP-{zUBPUeT%9y5Ul^tVoYr3`hV}IXwq8SSNOra{VwgoQt{^nJ z3vjiptS=#Hgt}Vl^2Lz+Wov)M^^vbK@W=uo3oEPgu0G1Ev(Cq+7bDojT=V0}T00ZR zJbyQ-0c~Oyo7xlK8`O%DR45U0I3NqrbqLXggCR{F3*dU_nt1ei4+z zRcoXJLuB&l@W_)3t>Z^{+fF0#S8}D0GJb7~6%nhn99(&`pBg$k<+^3-xR;Ta?~&0Q z#0f^G6+>TGq=K@C=~Ah8a$^583wYMOGq@V)oMp$p`j&72HjKl5?+ebWLV#;t0S37i zu>X^u`~EBb1zkInerg20p|g=~dBmOhVOac@0j2{+^AQ>hcryV%TEZL=e=K>5aT*)t0FR2mov;T7{ZAX;$Vnmiqimbo&n8 zyb>{+RFZTpID(L}q)IN$F+efvGjSPfKh9h6&3?_rkK1C)jAu%7te;}@Bh1Ktgd4Wu z5G24;F*iiI9w7AdNKw&j{4oaFTXC8=+qqhH0fE$rH@J9(@M9qMvYjZ=VPFijb>T${aDHoX0?LVLTgFO&g&paF9oc>31_Uh#18U9dLh>b0$h1c<&5u+ik8WXx)@z=S= zra5Hm2`O|Vb^UX8JVXNu^rp}26gvDlLw86MPa+ra-ZYGlv_e8<%0$AI<;vYvD7m0{ ze1_(o85VR;P4hi7T2ogi=iYhko%%g`TkWD_QK-Oz$DXaIlvXnE%PcNM@k-LU-_f!0 z9oaz8-LSOtYOSQF`|)<xBjQ6`tCSt9wn4wdTMqOM`Ja*D=ae#X;$4XHDvt8#1;WCaM z$zt+YBGN<#;K}~Z_EE3_xDqCO#PrzAxA9F~ADFx@wl2#vhLsPi)TMKs?)pKg^N@YI zWJ4P>zq(TzPUq7ArvTjoMSQ}n#Eb+I+SB?T3F8on4&>w*`x&(sd1AHKom!vl)4Nj* zwD@7v`hRVMQ7^|Pf3_p27}lBiI+{ccYLV!@`G?UG#To0=ZIC>l#edqC#mw-*3?gf( z9@J<~w!LobKwPHUN8Lu}s;>>Y{32S5-#BOD2+;1w^!I~%6jg*T&_>>g#vlzml56|% zhJM#8bA>FFu8B5RjBZ>MHI)HObF5QLb6i2?l>=H^?n_)5TMv`R|YMegJIJOeRii`addWJ zoLRx$0^wSPEVU!vJbAKYplV?e^&CsMZ^COCo=M*DJUe4=(-;(DH+C6gO5!mDwjl|a z=V$^P;n6)lE%mU;4o)===OaPhlEoSG+bB1AZAy*q-aeQZLuk0VIvJO`*@~B&qXYPO-XIO zYapdXWMV3h^GUB{6dIe8idSTWx5g{uFO<=-JLvAjA}>z zD4PIK=$6`p0+uPpJ2sT-)nOV~F$y33KyT>;965%)0d$rVxCfKq;r^ECx30sN6ser! zbDqjf5^p^zD607vS^Whle)5Z|CWo7C1bYl}=3T-{r8x6`^q+al5Wfu$Zliqo0+V(9 zqiX%zFVWS3Jtm$&1XZX39GJ>!m|q-f`CpzV%S(PPcOGwm!?sDy;HKN|f0TZoh-5>o z_ImIBZ;SKpGB{j9=k_C6(9moLrDNXzv7PpTA)nYXVL)>EsU>R%i-b8Mi=U>t>iZ1u z2{Ae$hU@prXZ@3@Qg~>ikj!frw#1>mX@dz1^$l}E(wN5C&Cok7=ie(AUj8UA&?)s% z7Ru}UGpXge&!PLP&eA`@7;sDk1q^o5Se-?J))+ztdetP^Rt96Sb|pPa9d7acvOK(U z;p0VGsu3z`s#3om@HwY(%i?ik1U98Vsfl&&~%pTF7 zp?W(3rWd6uLK7;VlxZ$ASy=d2$D|$WO+LDx-FQDcIsTnfSS#cj`jfGD(S@Yh;`X6B zM!R-; zLy^Th&8#L}m%}ynGCxnP_6^(F>4hv@?QzW{XvJwa&G}aL3$$-T0e=P-78d@(-{b1m zH#7+LH{ATD6-9YiW9RZ?WR2)QzuMl~?!DINWn@qiIc0$r@-^eg+)z2a8eK@pXrq_S zTAr3%9Z#t9-X?0eYa)A*m&!ooYr{60GAkvdnK?T|sZbHobW=hn{ON{2?K8oK<<`%6 zHImR(7o{wOcEnoPcjLDZO}D--$OEK_nzx%rr)&_Drf$rlM^gd9{MBR+b=~W!QIV5q zD1%jTpR%{bs|FF3*xQ&$4+?7TnuWt(Wn|vJ;DL;TY#K@*D)*kg@)<#^n7psOy1Uu$ zLek&lN@H31!dIi4y0H+xE!rHPzNu|1_L!O)!~iq~$(nV!QqGKy0{GinRs0_nGp?DJ z1r5TJ@*dpz{PYBvoJmBy`94{jE|t>7;fmpyO=8#%41U2w8meW9{Jr{KSmY~fCteLt zjG>nFLexA9;M^*@m|;hfrK}L!*jo}ibEIA`Ytp8NJY6(=+5GF~`rMNw6RDJt&S$Tx zp;hCgbG#p6s{X0!ld9X7@on0BDgBlMHK$d3Sd#DbRkgD+$hYn7`9GT7VyWrYRPJ^x z6E>SN5^mcJ@UFf0eM39Yf)8PDTr#{-`o0wA+iMt^7JTDUTQ6|ZG=M)1Qzp>@TQX~b!wXSzcOqArzYO!?xM6O)m1Spz{I2BFEdL$J-B+>RCp?fQy(8eOf6RPZ(&V~?*S>xNJLjEmwrbtacRA3zoC>Io*@SNmSq~e_u4UpIf4+mj8dPck(h9qMRkaC|!7sWG#cCf>GK znDFi5J@Y-XIJ{@E+l&1xQqZo5(3dr@*DA40$KC5^@-_n_zv;)&x_je*M~Tpk718OYg{%=44Bs&2mNBjEE=I zwwC>4ixu0uK}pot!jOBCrmJ;LEEs~-wgMsv>|=F^@;Zu!>JO_Gu2C#KNB(7La^}j4 z?n2eRqrZC5t5%_%u8Ze?$`WhreU{6a%>ftq0iRJ+=nAX#_YYffX(yR>pMLKmii+iv z0w?F4zVG#8q)snRr8DU{_SH+<6F%-XrsMYhd^t-*9QAVIjk)?tWIZ=;{7cr_)#h8B z6hV{eXF*FM)y=T8lNt1?&Q)IcwW+K5)>=0Y*Xha5{Ql32oGSM@6@#Yb-5}+uo>!v> zM=v6F%+o0gIA^}u?~Oh!Q=a#k#r{)2zO|{9btd&leCoUHSd=S=l;B@!S91=QdzZYz z2M)uj-15bJTUv|SHJ;x^IW=6o4a2r6d6aohGv@`p_J6H)Wsq~z`|z~?EM?-Xeg9Sl z*&hknL9db_Kx5PCVuI<)U{PYmZ8I$;O7G4uemC~;QFN6o{6431@E+N^)`gvxs$5TF zQ|LY!xVJc6`Q4~L$<0|g))m3V7(jC3D3Hya=-t;tlTh9vE$KzO>0HfIb z{%Ukl#oX!)%(5a^Y3D8Y=zP$A?b7&p*n{?~UxZl;PhD*xw}`=n8m1IO)fgr7%es~i z(kuCjb?uH<{7r&Z!vQmBXxQws5^ps=U9Z3)*u30hL0RIKvOOy6H~9lVJ9LQ%+J+Sr z@4g#Xfuzn?{W>!)&lqSyq3}XivAM@JDV!=qgEOnwx(by4s%P#GuVqfoUu}_-&()c9 zj?{1N_b>74=I5Fojw;(vi_);r7*)nOX>{{`-S0a*yq&2tS*@rq3Z2{2Ei8u*PPA~@ zE>ss^maw*LTiMOI3EaMO!fz+ow6*<1qOT%+sjwG?{_R)z!t6B()&~Lv$wpo5B8-y% zX}aiE2GG1lF7)R{zx#eBj+ek(x2|2onk+nZ^81v0X2Q#$kr?SLiC0W^wi?>Y_V8rC zDQa6_QMsm|&!S*b6`g&j_Ui4?mzVq z`^XwGO}`}W&#QJvdCegc)Bfj`LBPrd`TRLd#S9ZHVF+m7VxqmtYnxL7TvUOK1>h?5 zZ8P75s=)#S10y3NV`F1M3+?FW$Qu}tg=kkEwoldAFM_!Tiasw)5(iARoZ+24ht8ml}db zFiocx7e(3FaJmkGg_l+xUR1O>BF~DwDBO=t21HTe3{*O?TRA3H0Wtc(ENz6AjnV!Q zEHa5io@RNUHRZoxq52DGb2z?q6zBk!e!TB!Lbcv=Ao`+>Iu{L1f`M!5c9m*f2{WAi z-W0-I*@*?!<9kAG_;D#<-x2H?d+HFbTNC?W?`^0MX^%EFGn1-NhqF%1Yxg*-5zM=m zR)CaEs!Lr)a7@n>7cCiAi!eh&i}3oD7NIE??g&G!uO6^AsYg$+JM_?@p#|i=pYToR za9$ro?WTY~&JDFazt}8Bnc{#Xpe@}tS*B&Ps2J7wBLgRo45eF8Dii=+9kE?uEg5@G z)b+B2zy*D&m1bf^cKi;^zyMqNjO`HdyE`UbZ4p_XQYB>-2 z11fVAjKS{xv)FU1eXt!ymgpezFV)D^Uz5N~^=bxFIBENF0{0)0hlPcSlb}HJOK~mN zJN8TO*N6oxjm6*?k1UZP5@0#2^1hAUD|xN{*Vjj8zp1{}?_TTgj-3Zy zo}RHA0Sq@k@f-_YqyCoJJ;)a{Kct_btZy;T|Bs(5sJ$XE9GP;Ypf*6j8boycQBQ9c z^fIlitl)KPsV65VC@>bsw3F9HzkGaPVyFyN+uDD8Thbi_;*)p%optiJ?&FY>hp6 zliN>l@7MMnNSa%KgbY(?CsL;(5qM}`DXFftcEyIy|TQVZ&KWIjj3W!|fdODWkHymoVERb@Uq z?qC)K!VxiOqbWcinGXfqOcPL|>Fn%$9TgA$Nk|BYdM$|UPgrX2y+Vvy>T(R54W^&( z*nbiXH|k#jwbb3MExl%M4|n&|o9j#Q7lA!BY?&w>G?=kdz=4*c7tHdh`Lq0Uam_gN zbanAr4fHiMxDL*MsHvSi3wRCpd#WZ4(v%8rfj=%l?yBu&GfqBsmd9EO_@Ek_n4tOL zLW6ndvn8ytQK)ia|2Uu^wGA{mWjKI99; z%~9vd+QrrH8y>RK-h%26P&l4k-@D0!g`9DHf z^;kZle?DRgVln`CZMIQ<<%hb2YU~Zq_&Cr{f$ma>Y8q6l+D4^rc2Ap6n}%PeW~K~D zf-Bk(1TgB^!lU!Eh1%V9Y8{Li60lT>#QrucUfa34x>}5}W!n25rY*&(6lG(GOZxzc zB>7~RFce(&i$LcIX6-_k{Pp0f-`(AH2nH7SzhJT&_zm088Bj~IQJc4MhsRk!Ex5lU z#_PNNf!qsFUD`ikB@jn01!5D^P+>0io$s%sF6M{npSq4k>ks2}e9_*kg>QMb;qb(< zN4d+fg3dHhBgb08VX!}-%kjjB@Ck%tpb7Zb$rro|8guXlAD}xdRoc>mw=g9&>I?7x zqo3Tb@1P~$N9~92s%(J!m<8E?AK_}OD)`8jc_{W@KmY3)_^)T+zn+2r*Jt2b6ny;M m-j*EsEP?;PK;1muL$jV?b#hbiI|YA&CM&5V0T+A!^}hjnGJRVB literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/learning-xor/index.html b/apps/website/public/ru/learn/learning-xor/index.html new file mode 100644 index 0000000000..5c13106d59 --- /dev/null +++ b/apps/website/public/ru/learn/learning-xor/index.html @@ -0,0 +1,399 @@ + + + + + + +Учим XOR: курс о нейросетях, урок 20 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Учим XOR

+

Вы узнаете

Почему один нейрон не может выучить XOR и как это делает скрытый слой, обученный обратным распространением.

+

XOR равен 1, когда ровно один из двух входов равен 1. Никакая прямая не отделяет случаи, дающие 1, от дающих 0, поэтому один нейрон выучить его не может. Скрытый слой изгибает пространство: спека обучает сеть 2-8-1 из ReLU обратным распространением, lr 0.05, из фиксированных начальных весов. Её потеря падает с 0.8896 в эпохе 1 до 1.8e-13 после 2000 эпох, а четыре ответа выходят в пределах 4e-7 от 0, 1, 1 и 0. Виджет проводит это обучение в вашем браузере, заново для каждой точки кривой. Спека mlp.t27 хранит сеть и тест, что она учится.

+

Попробовать

Отведите эпохи назад к 100 и прочитайте четыре ответа; затем найдите эпоху, где кривая перестаёт падать.

+

Открыть интерактивный урок →

+
XOR: a network learns what one neuron cannot
XOR: a network learns what one neuron cannot ↗
+

A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders.

+

specs/ml/pathway/mlp.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// ReLU activation for hidden layers | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward computed the hidden layer and wrote it into `output` (the
+// second layer never ran); init called an undeclared `alloc_f32`; the tests
+// called undeclared `create_test_*` helpers; and the invariants asserted `true`.
+// The MLP is now two layers, h = relu(W1 x + b1) and y = W2 h + b2, over buffers
+// the caller owns. train_step adds backpropagation with an SGD update, and the
+// tests train the network on XOR, which no single linear layer can fit.
+
+module Mlp;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const MNIST_INPUT_SIZE : u32 = 784;
+    const MNIST_OUTPUT_SIZE : u32 = 10;
+    const DEFAULT_HIDDEN_SIZE : u32 = 128;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const MLPConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+        output_size : u32,
+    };
+
+    pub const MLPState = struct {
+        w1 : []f32,
+        b1 : []f32,
+        w2 : []f32,
+        b2 : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // One dense layer: out[o] = sum_i w[o * n_in + i] in[i] + b[o], relu when asked
+    fn layer(input: []const f32, w: []const f32, b: []const f32, n_in: u32, n_out: u32, relu: bool, out: []f32) -> void {
+        var o : usize = 0;
+        while (o < n_out) {
+            var sum : f32 = b[o];
+            var i : usize = 0;
+            while (i < n_in) {
+                sum = sum + w[o * n_in + i] * input[i];
+                i = i + 1;
+            }
+            if (relu and sum < 0.0) {
+                sum = 0.0;
+            }
+            out[o] = sum;
+            o = o + 1;
+        }
+    }
+
+    // h = relu(W1 x + b1) into `hidden`, y = W2 h + b2 into `output`
+    fn forward(input: []const f32, state: MLPState, hidden: []f32, output: []f32, config: MLPConfig) -> void {
+        layer(input, state.w1, state.b1, config.input_size, config.hidden_size, true, hidden);
+        layer(hidden, state.w2, state.b2, config.hidden_size, config.output_size, false, output);
+    }
+
+    // He-scaled deterministic init: w in [-1, 1) sqrt(2 / fan_in) from a fixed hash of the
+    // index (salt tells the layers apart); every bias 0
+    fn init_weights(w: []f32, fan_in: u32, salt: usize) -> void {
+        const scale : f32 = sqrt(2.0 / @as(f32, @floatFromInt(fan_in)));
+        var k : usize = 0;
+        while (k < w.len) {
+            const h : u32 = @as(u32, @intCast(((k + salt) * 2654435761) % 1000));
+            w[k] = (@as(f32, @floatFromInt(h)) / 500.0 - 1.0) * scale;
+            k = k + 1;
+        }
+    }
+
+    fn zero(v: []f32) -> void {
+        var k : usize = 0;
+        while (k < v.len) {
+            v[k] = 0.0;
+            k = k + 1;
+        }
+    }
+
+    fn init(state: MLPState, config: MLPConfig) -> void {
+        init_weights(state.w1, config.input_size, 1);
+        zero(state.b1);
+        init_weights(state.w2, config.hidden_size, 7);
+        zero(state.b2);
+    }
+
+    // One SGD step on the loss 0.5 * sum_o (y_o - t_o)^2; returns the loss before the step.
+    //   d2_o = y_o - t_o                                   (output error)
+    //   d1_i = [z_i > 0] sum_o W2[o][i] d2_o                (backpropagated through relu)
+    //   W2 -= lr d2 h^T, b2 -= lr d2;  W1 -= lr d1 x^T, b1 -= lr d1
+    fn train_step(input: []const f32, target: []const f32, state: MLPState, hidden: []f32, delta: []f32, output: []f32, lr: f32, config: MLPConfig) -> f32 {
+        forward(input, state, hidden, output, config);
+        var loss : f32 = 0.0;
+        var o : usize = 0;
+        while (o < config.output_size) {
+            const e = output[o] - target[o];
+            loss = loss + 0.5 * e * e;
+            o = o + 1;
+        }
+        var i : usize = 0;
+        while (i < config.hidden_size) {
+            var back : f32 = 0.0;
+            if (hidden[i] > 0.0) {
+                o = 0;
+                while (o < config.output_size) {
+                    back = back + state.w2[o * config.hidden_size + i] * (output[o] - target[o]);
+                    o = o + 1;
+                }
+            }
+            delta[i] = back;
+            i = i + 1;
+        }
+        o = 0;
+        while (o < config.output_size) {
+            const d2 = output[o] - target[o];
+            i = 0;
+            while (i < config.hidden_size) {
+                state.w2[o * config.hidden_size + i] = state.w2[o * config.hidden_size + i] - lr * d2 * hidden[i];
+                i = i + 1;
+            }
+            state.b2[o] = state.b2[o] - lr * d2;
+            o = o + 1;
+        }
+        i = 0;
+        while (i < config.hidden_size) {
+            var j : usize = 0;
+            while (j < config.input_size) {
+                state.w1[i * config.input_size + j] = state.w1[i * config.input_size + j] - lr * delta[i] * input[j];
+                j = j + 1;
+            }
+            state.b1[i] = state.b1[i] - lr * delta[i];
+            i = i + 1;
+        }
+        return loss;
+    }
+
+    fn mnist() -> MLPConfig {
+        return MLPConfig{ .input_size = MNIST_INPUT_SIZE, .hidden_size = DEFAULT_HIDDEN_SIZE, .output_size = MNIST_OUTPUT_SIZE };
+    }
+
+    // which: 0 = output[index], 1 = min over every output, 2 = number of outputs written,
+    // on the MNIST shape with input pixel k = (k % 7) / 7
+    fn mnist_forward(which: u8, index: usize) -> f32 {
+        var w1 : [784 * 128]f32 = undefined;
+        var b1 : [128]f32 = undefined;
+        var w2 : [128 * 10]f32 = undefined;
+        var b2 : [10]f32 = undefined;
+        const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 };
+        init(state, mnist());
+        var input : [784]f32 = undefined;
+        var k : usize = 0;
+        while (k < 784) {
+            input[k] = @as(f32, @floatFromInt(k % 7)) / 7.0;
+            k = k + 1;
+        }
+        var hidden : [128]f32 = undefined;
+        var output : [11]f32 = [-99.0] ** 11;
+        forward(&input, state, &hidden, &output, mnist());
+        if (which == 0) {
+            return output[index];
+        }
+        var min_h : f32 = hidden[0];
+        var written : f32 = 0.0;
+        k = 0;
+        while (k < 128) {
+            min_h = @min(min_h, hidden[k]);
+            k = k + 1;
+        }
+        k = 0;
+        while (k < 11) {
+            if (output[k] != -99.0) {
+                written = written + 1.0;
+            }
+            k = k + 1;
+        }
+        if (which == 1) {
+            return min_h;
+        }
+        return written;
+    }
+
+    // which: 0 = w1.len written by init, 1 = b1[0], 2 = b2[0], 3 = largest |w1|
+    fn mnist_init(which: u8) -> f32 {
+        var w1 : [784 * 128]f32 = [9.0] ** (784 * 128);
+        var b1 : [128]f32 = [9.0] ** 128;
+        var w2 : [128 * 10]f32 = [9.0] ** (128 * 10);
+        var b2 : [10]f32 = [9.0] ** 10;
+        init(MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 }, mnist());
+        var written : f32 = 0.0;
+        var largest : f32 = 0.0;
+        var k : usize = 0;
+        while (k < w1.len) {
+            if (w1[k] != 9.0) {
+                written = written + 1.0;
+            }
+            largest = @max(largest, @abs(w1[k]));
+            k = k + 1;
+        }
+        if (which == 0) {
+            return written;
+        }
+        if (which == 1) {
+            return b1[0];
+        }
+        if (which == 2) {
+            return b2[0];
+        }
+        return largest;
+    }
+
+    // Train a 2-8-1 network on XOR for `epochs` passes over the four cases.
+    // which: 0 = total loss of the first epoch, 1 = total loss of the last epoch,
+    // 2 + c = the trained network's output for case c
+    fn xor(epochs: u32, which: usize) -> f32 {
+        const cfg = MLPConfig{ .input_size = 2, .hidden_size = 8, .output_size = 1 };
+        var w1 : [16]f32 = undefined;
+        var b1 : [8]f32 = undefined;
+        var w2 : [8]f32 = undefined;
+        var b2 : [1]f32 = undefined;
+        const state = MLPState{ .w1 = &w1, .b1 = &b1, .w2 = &w2, .b2 = &b2 };
+        init(state, cfg);
+        const xs : [8]f32 = [0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0];
+        const ts : [4]f32 = [0.0, 1.0, 1.0, 0.0];
+        var hidden : [8]f32 = undefined;
+        var delta : [8]f32 = undefined;
+        var output : [1]f32 = undefined;
+        var first : f32 = 0.0;
+        var last : f32 = 0.0;
+        var e : u32 = 0;
+        while (e < epochs) {
+            var total : f32 = 0.0;
+            var c : usize = 0;
+            while (c < 4) {
+                total = total + train_step(xs[c * 2 .. c * 2 + 2], ts[c .. c + 1], state, &hidden, &delta, &output, 0.05, cfg);
+                c = c + 1;
+            }
+            if (e == 0) {
+                first = total;
+            }
+            last = total;
+            e = e + 1;
+        }
+        if (which == 0) {
+            return first;
+        }
+        if (which == 1) {
+            return last;
+        }
+        forward(xs[(which - 2) * 2 .. (which - 2) * 2 + 2], state, &hidden, &output, cfg);
+        return output[0];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // 784 -> 128 -> 10: exactly the 10 outputs are written, the 11th slot is untouched
+    test forward_output_size
+        given written = mnist_forward(2, 0)
+        when spare = mnist_forward(0, 10)
+        then written == 10.0 and spare == -99.0
+
+    // The hidden layer is relu, so no hidden unit is negative
+    test forward_relu_activation
+        given min_hidden = mnist_forward(1, 0)
+        then min_hidden >= 0.0
+
+    // init writes every one of the 784 * 128 first-layer weights, each within sqrt(2 / 784) = 0.05051
+    test init_allocation_sizes
+        given written = mnist_init(0)
+        when largest = mnist_init(3)
+        then written == 100352.0 and largest <= 0.0506 and largest > 0.0
+
+    test init_bias_initialization
+        given b1 = mnist_init(1)
+        when b2 = mnist_init(2)
+        then b1 == 0.0 and b2 == 0.0
+
+    // Backpropagation learns XOR: the loss falls by more than 100x, and each output is within 0.1
+    test train_step_learns_xor
+        given first = xor(2000, 0)
+        when last = xor(2000, 1)
+        then last < first / 100.0 and @abs(xor(2000, 2)) < 0.1 and @abs(xor(2000, 3) - 1.0) < 0.1 and @abs(xor(2000, 4) - 1.0) < 0.1 and @abs(xor(2000, 5)) < 0.1
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input_size == MNIST_INPUT_SIZE (784)
+    invariant mlp_constraint_0
+        assert mnist().input_size == 784
+
+    // output_size == MNIST_OUTPUT_SIZE (10)
+    invariant mlp_constraint_1
+        assert mnist().output_size == 10
+
+    // hidden_size > 0
+    invariant mlp_constraint_2
+        assert mnist().hidden_size > 0
+
+    // w1.size() == input_size * hidden_size
+    invariant mlp_constraint_3
+        assert mnist().input_size * mnist().hidden_size == 100352
+
+    // w2.size() == hidden_size * output_size
+    invariant mlp_constraint_4
+        assert mnist().hidden_size * mnist().output_size == 1280
+
+    // b1.size() == hidden_size
+    invariant mlp_constraint_5
+        assert DEFAULT_HIDDEN_SIZE == 128
+
+    // b2.size() == output_size
+    invariant mlp_constraint_6
+        assert MNIST_OUTPUT_SIZE == 10
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/lstm-gates/card.png b/apps/website/public/ru/learn/lstm-gates/card.png new file mode 100644 index 0000000000000000000000000000000000000000..308b52482aa44be2037f16ce560cbbe18c2488a4 GIT binary patch literal 59392 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 Z0V}%G>rPR@R;l;weY=53&-L)Re*^s6OWgnf literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/lstm-gates/index.html b/apps/website/public/ru/learn/lstm-gates/index.html new file mode 100644 index 0000000000..5e166850d7 --- /dev/null +++ b/apps/website/public/ru/learn/lstm-gates/index.html @@ -0,0 +1,400 @@ + + + + + + +Вентили LSTM: курс о нейросетях, урок 23 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Вентили LSTM

+

Вы узнаете

Как вентили забывания, входа и выхода LSTM решают, что ячейка хранит, записывает и показывает.

+

Ячейка LSTM хранит отдельную память c и три вентиля, каждый это сигмоида между 0 и 1: забывание масштабирует старую память, вход впускает новое содержимое g, а выход решает, сколько памяти показать. c' = f c + i g и h' = o tanh(c'). В фикстуре спеки каждый вес равен 0, поэтому каждый вентиль это сигмоида своего смещения: при вентиле забывания 0.9975 и вентиле входа 0.0025 память 1 выходит как 0.9975, а выход равен 0.7587. Так как c проходит лишь с умножением на f, её градиент тоже переживает много шагов. Спека lstm_single.t27 вычисляет ячейку.

+

Попробовать

Загрузите Remember, а затем Forget и сравните новую память; затем запишите с открытым вентилем входа.

+

Открыть интерактивный урок →

+
LSTM gates: how a cell decides what to keep
LSTM gates: how a cell decides what to keep ↗
+

Set the biases of the forget, input and output gates and the old memory: the new memory is forget x old + input x candidate, and the output shows tanh of it through the output gate.

+

specs/ml/recurrent/lstm_single.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// LSTM solves vanishing gradient problem | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: called `@sigmoid` and `@tanh`, which Zig does not have; each gate weight
+// was one number per INPUT, indexed `i % hidden_size`, so it was not an LSTM; and
+// every test asserted `true`. Now each gate has its own matrices, W_x
+// (hidden x input) and W_h (hidden x hidden), and a bias:
+//   i = s(z_i), f = s(z_f), g = tanh(z_g), o = s(z_o),  z = W_x x + W_h h + b
+//   c' = f c + i g,  h' = o tanh(c')
+// backward gives every gradient of one step, and the tests check it against finite
+// differences.
+
+module LstmCell;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const FORGET_BIAS_INIT : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const LSTMConfig = struct {
+        input_size : u32,
+        hidden_size : u32,
+    };
+
+    pub const LSTMState = struct {
+        h : []f32,
+        c : []f32,
+    };
+
+    pub const LSTMWeights = struct {
+        W_ii : []f32,
+        W_hi : []f32,
+        b_i : []f32,
+        W_if : []f32,
+        W_hf : []f32,
+        b_f : []f32,
+        W_ig : []f32,
+        W_hg : []f32,
+        b_g : []f32,
+        W_io : []f32,
+        W_ho : []f32,
+        b_o : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    fn sigmoid(z: f32) -> f32 {
+        return 1.0 / (1.0 + exp(-z));
+    }
+
+    // Pre-activation of one gate for hidden unit u: W_x[u] . x + W_h[u] . h + b[u]
+    fn pre(w_x: []const f32, w_h: []const f32, b: []const f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig) -> f32 {
+        var z : f32 = b[u];
+        var j : usize = 0;
+        while (j < config.input_size) {
+            z = z + w_x[u * config.input_size + j] * x[j];
+            j = j + 1;
+        }
+        var k : usize = 0;
+        while (k < config.hidden_size) {
+            z = z + w_h[u * config.hidden_size + k] * h[k];
+            k = k + 1;
+        }
+        return z;
+    }
+
+    fn forward(input: []const f32, state: LSTMState, weights: LSTMWeights, output_state: LSTMState, config: LSTMConfig) -> void {
+        var u : usize = 0;
+        while (u < config.hidden_size) {
+            const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config));
+            const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config));
+            const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config));
+            const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config));
+            output_state.c[u] = fg * state.c[u] + ig * gg;
+            output_state.h[u] = og * tanh(output_state.c[u]);
+            u = u + 1;
+        }
+    }
+
+    // Adds dz * (x, h, 1) into one gate's weight gradients, and dz * W into grad_input / grad_state.h
+    fn spread(dz: f32, w_x: []const f32, w_h: []const f32, gw_x: []f32, gw_h: []f32, gb: []f32, x: []const f32, h: []const f32, u: usize, config: LSTMConfig, grad_input: []f32, grad_h: []f32) -> void {
+        var j : usize = 0;
+        while (j < config.input_size) {
+            gw_x[u * config.input_size + j] = gw_x[u * config.input_size + j] + dz * x[j];
+            grad_input[j] = grad_input[j] + dz * w_x[u * config.input_size + j];
+            j = j + 1;
+        }
+        var k : usize = 0;
+        while (k < config.hidden_size) {
+            gw_h[u * config.hidden_size + k] = gw_h[u * config.hidden_size + k] + dz * h[k];
+            grad_h[k] = grad_h[k] + dz * w_h[u * config.hidden_size + k];
+            k = k + 1;
+        }
+        gb[u] = gb[u] + dz;
+    }
+
+    // One step back. grad_output = dL/dh', grad_cell = dL/dc' from later steps. Writes
+    // dL/dx, dL/dh, dL/dc and ADDS the weight gradients into grad_weights.
+    //   do = dh' tanh(c');  dc = dh' o (1 - tanh^2 c') + grad_cell
+    //   dz_o = do o (1 - o), dz_f = dc c f (1 - f), dz_i = dc g i (1 - i), dz_g = dc i (1 - g^2)
+    //   dL/dc = dc f
+    fn backward(grad_output: []const f32, grad_cell: []const f32, input: []const f32, state: LSTMState, weights: LSTMWeights, config: LSTMConfig, grad_input: []f32, grad_state: LSTMState, grad_weights: LSTMWeights) -> void {
+        var j : usize = 0;
+        while (j < config.input_size) {
+            grad_input[j] = 0.0;
+            j = j + 1;
+        }
+        var u : usize = 0;
+        while (u < config.hidden_size) {
+            grad_state.h[u] = 0.0;
+            u = u + 1;
+        }
+        u = 0;
+        while (u < config.hidden_size) {
+            const ig = sigmoid(pre(weights.W_ii, weights.W_hi, weights.b_i, input, state.h, u, config));
+            const fg = sigmoid(pre(weights.W_if, weights.W_hf, weights.b_f, input, state.h, u, config));
+            const gg = tanh(pre(weights.W_ig, weights.W_hg, weights.b_g, input, state.h, u, config));
+            const og = sigmoid(pre(weights.W_io, weights.W_ho, weights.b_o, input, state.h, u, config));
+            const c_new = fg * state.c[u] + ig * gg;
+            const tc = tanh(c_new);
+            const dc = grad_output[u] * og * (1.0 - tc * tc) + grad_cell[u];
+            const dz_o = grad_output[u] * tc * og * (1.0 - og);
+            const dz_f = dc * state.c[u] * fg * (1.0 - fg);
+            const dz_i = dc * gg * ig * (1.0 - ig);
+            const dz_g = dc * ig * (1.0 - gg * gg);
+            grad_state.c[u] = dc * fg;
+            spread(dz_i, weights.W_ii, weights.W_hi, grad_weights.W_ii, grad_weights.W_hi, grad_weights.b_i, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_f, weights.W_if, weights.W_hf, grad_weights.W_if, grad_weights.W_hf, grad_weights.b_f, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_g, weights.W_ig, weights.W_hg, grad_weights.W_ig, grad_weights.W_hg, grad_weights.b_g, input, state.h, u, config, grad_input, grad_state.h);
+            spread(dz_o, weights.W_io, weights.W_ho, grad_weights.W_io, grad_weights.W_ho, grad_weights.b_o, input, state.h, u, config, grad_input, grad_state.h);
+            u = u + 1;
+        }
+    }
+
+    // The fixture: input 3, hidden 2. All 48 weights live in one buffer, per gate
+    // W_x (6), W_h (4), b (2), in the gate order i, f, g, o.
+    fn cfg() -> LSTMConfig {
+        return LSTMConfig{ .input_size = 3, .hidden_size = 2 };
+    }
+
+    fn weights_of(w: []f32) -> LSTMWeights {
+        return LSTMWeights{
+            .W_ii = w[0..6], .W_hi = w[6..10], .b_i = w[10..12],
+            .W_if = w[12..18], .W_hf = w[18..22], .b_f = w[22..24],
+            .W_ig = w[24..30], .W_hg = w[30..34], .b_g = w[34..36],
+            .W_io = w[36..42], .W_ho = w[42..46], .b_o = w[46..48],
+        };
+    }
+
+    // Deterministic weights in [-0.5, 0.5]; the forget biases start at FORGET_BIAS_INIT
+    fn fill(w: []f32) -> void {
+        var k : usize = 0;
+        while (k < 48) {
+            w[k] = @as(f32, @floatFromInt((k * 7 + 3) % 11)) / 10.0 - 0.5;
+            k = k + 1;
+        }
+        w[22] = FORGET_BIAS_INIT;
+        w[23] = FORGET_BIAS_INIT;
+    }
+
+    // L = 0.5 h'_0 - 0.3 h'_1 + 0.2 c'_0 + 0.1 c'_1 after one step, with one input, one h or
+    // one c entry moved by `delta` (which: 0 = none, 1 + j = x_j, 4 + k = h_k, 6 + k = c_k,
+    // 8 = b_f[1])
+    fn loss(which: usize, delta: f32) -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        var x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        if (which >= 1 and which <= 3) {
+            x[which - 1] = x[which - 1] + delta;
+        }
+        if (which >= 4 and which <= 5) {
+            h[which - 4] = h[which - 4] + delta;
+        }
+        if (which >= 6 and which <= 7) {
+            c[which - 6] = c[which - 6] + delta;
+        }
+        if (which == 8) {
+            w[23] = w[23] + delta;
+        }
+        var h_out : [2]f32 = [0.0] ** 2;
+        var c_out : [2]f32 = [0.0] ** 2;
+        forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg());
+        return 0.5 * h_out[0] - 0.3 * h_out[1] + 0.2 * c_out[0] + 0.1 * c_out[1];
+    }
+
+    // The analytic gradient of that loss, same `which` numbering
+    fn grad(which: usize) -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        const grad_output : [2]f32 = [0.5, -0.3];
+        const grad_cell : [2]f32 = [0.2, 0.1];
+        var gx : [3]f32 = [0.0] ** 3;
+        var gh : [2]f32 = [0.0] ** 2;
+        var gc : [2]f32 = [0.0] ** 2;
+        var gw : [48]f32 = [0.0] ** 48;
+        backward(&grad_output, &grad_cell, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw));
+        if (which >= 1 and which <= 3) {
+            return gx[which - 1];
+        }
+        if (which >= 4 and which <= 5) {
+            return gh[which - 4];
+        }
+        if (which >= 6 and which <= 7) {
+            return gc[which - 6];
+        }
+        return gw[23];
+    }
+
+    // Sum of |every gradient| when grad_output and grad_cell are both 0
+    fn zero_upstream_total() -> f32 {
+        var w : [48]f32 = undefined;
+        fill(&w);
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.1, 0.2];
+        var c : [2]f32 = [0.3, 0.4];
+        const zeros : [2]f32 = [0.0, 0.0];
+        var gx : [3]f32 = [0.0] ** 3;
+        var gh : [2]f32 = [0.0] ** 2;
+        var gc : [2]f32 = [0.0] ** 2;
+        var gw : [48]f32 = [0.0] ** 48;
+        backward(&zeros, &zeros, &x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), cfg(), &gx, LSTMState{ .h = &gh, .c = &gc }, weights_of(&gw));
+        var total : f32 = @abs(gx[0]) + @abs(gx[1]) + @abs(gx[2]) + @abs(gh[0]) + @abs(gh[1]) + @abs(gc[0]) + @abs(gc[1]);
+        var k : usize = 0;
+        while (k < 48) {
+            total = total + @abs(gw[k]);
+            k = k + 1;
+        }
+        return total;
+    }
+
+    fn slope(which: usize) -> f32 {
+        return (loss(which, 0.001) - loss(which, -0.001)) / 0.002;
+    }
+
+    // which: 0 = h'_0, 1 = c'_0 for a 1-unit cell with every weight 0 and the given biases
+    fn bias_only(b_i: f32, b_f: f32, b_g: f32, b_o: f32, c_prev: f32, which: u8) -> f32 {
+        var w : [48]f32 = [0.0] ** 48;
+        w[10] = b_i;
+        w[22] = b_f;
+        w[34] = b_g;
+        w[46] = b_o;
+        const x : [3]f32 = [1.0, 2.0, 3.0];
+        var h : [2]f32 = [0.0, 0.0];
+        var c : [2]f32 = [c_prev, 0.0];
+        var h_out : [2]f32 = [9.0] ** 2;
+        var c_out : [2]f32 = [9.0] ** 2;
+        forward(&x, LSTMState{ .h = &h, .c = &c }, weights_of(&w), LSTMState{ .h = &h_out, .c = &c_out }, cfg());
+        if (which == 0) {
+            return h_out[0];
+        }
+        return c_out[0];
+    }
+
+    fn valid_input() -> usize {
+        return cfg().input_size;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // All weights 0: every gate is s(0) = 0.5 or tanh(0) = 0, so c' = 0.5 c and h' = 0.5 tanh(c')
+    test forward_basic_case
+        given c_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 1)
+        when h_new = bias_only(0.0, 0.0, 0.0, 0.0, 0.8, 0)
+        then @abs(c_new - 0.4) < 0.000001 and @abs(h_new - 0.5 * tanh(c_new)) < 0.000001 and @abs(h_new - 0.1899745) < 0.000001
+
+    // A closed forget gate (b_f = -30) erases the old cell; an open one (b_f = 30) keeps it
+    test forward_basic_lstm
+        given erased = bias_only(0.0, -30.0, 0.0, 0.0, 0.8, 1)
+        when kept = bias_only(-30.0, 30.0, 0.0, 0.0, 0.8, 1)
+        then @abs(erased) < 0.000001 and @abs(kept - 0.8) < 0.000001
+
+    // A closed input gate and forget gate leave c' = 0, so h' = 0 whatever the output gate does
+    test forward_with_empty_input
+        given h_new = bias_only(-30.0, -30.0, 1.0, 30.0, 0.8, 0)
+        then @abs(h_new) < 0.000001
+
+    // dL/dx_j against central differences
+    test backward_basic_case
+        given g0 = grad(1)
+        when g2 = grad(3)
+        then @abs(g0 - slope(1)) < 0.0005 and @abs(grad(2) - slope(2)) < 0.0005 and @abs(g2 - slope(3)) < 0.0005
+
+    // dL/dh_k, dL/dc_k and dL/db_f[1] against central differences
+    test backward_basic_lstm
+        given gh0 = grad(4)
+        when gc1 = grad(7)
+        then @abs(gh0 - slope(4)) < 0.0005 and @abs(grad(5) - slope(5)) < 0.0005 and @abs(grad(6) - slope(6)) < 0.0005 and @abs(gc1 - slope(7)) < 0.0005 and @abs(grad(8) - slope(8)) < 0.0005
+
+    // With no upstream gradient nothing flows back
+    test backward_with_empty_grad
+        given total = zero_upstream_total()
+        then total == 0.0 and @abs(grad(1)) > 0.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.size() == config.input_size
+    invariant lstm_cell_constraint_0
+        assert valid_input() == 3
+
+    // state.h.size() == config.hidden_size
+    invariant lstm_cell_constraint_1
+        assert cfg().hidden_size == 2
+
+    // state.c.size() == config.hidden_size; the forget bias starts open
+    invariant lstm_cell_constraint_2
+        assert FORGET_BIAS_INIT > 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/max-pooling/card.png b/apps/website/public/ru/learn/max-pooling/card.png new file mode 100644 index 0000000000000000000000000000000000000000..92625cc031e1cc2b932a4b795bbcad77a25c5665 GIT binary patch literal 53369 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/max-pooling/index.html b/apps/website/public/ru/learn/max-pooling/index.html new file mode 100644 index 0000000000..067218c038 --- /dev/null +++ b/apps/website/public/ru/learn/max-pooling/index.html @@ -0,0 +1,222 @@ + + + + + + +Max pooling: максимум окна: курс о нейросетях, урок 11 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

Max pooling: максимум окна

+

Вы узнаете

Что оставляет max pooling, откуда, как он помнит, это взято и куда идёт градиент.

+

Max pooling оставляет наибольшее значение каждого окна и отбрасывает остальные, поэтому сети становится менее важно, где именно лежит признак. На сетке спеки 4 x 4 окна 2 x 2 с шагом 2 оставляют 4, 8, 9 и -2, взятые из клеток 5, 6, 13 и 11. Перекрывающиеся окна 3 x 3 с шагом 1 оставляют 8, 8, 9 и 9. При обратном проходе весь градиент окна идёт в его максимум: градиенты 1, 2, 3 и 4 попадают в клетки 5, 6, 13 и 11, а все остальные клетки получают 0. Спека maxpool2d_layer.t27 вычисляет выходы, их позиции и градиент.

+

Попробовать

Переключитесь на окна 3 x 3 и найдите клетку, общую для двух выходов; затем включите градиент для окон 2 x 2.

+

Открыть интерактивный урок →

+
Max pooling: what a network keeps when it shrinks a picture
Max pooling: what a network keeps when it shrinks a picture ↗
+

Pick a window size and stride and tap an output: max pooling keeps the largest value of its window and remembers where it was, and the gradient later goes to that one cell.

+

specs/ml/layers/maxpool2d_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Reduce spatial dimensions | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward and backward compared two values and threw them away
+// (placeholders), and every test asserted `result != undefined`. Max pooling now
+// runs over one H x W channel (row-major) with a k x k window and a stride. It
+// records each window's argmax, and backward sends each gradient back to that
+// element only. Padding and dilation are carried in the config but not read: the
+// layer assumes padding 0 and dilation 1.
+
+module Maxpool2d;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const MaxPool2DConfig = struct {
+        kernel_size : u32,
+        stride : u32,
+        padding : u32,
+        dilation : u32,
+        return_indices : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Output side for an input side n: (n - k) / stride + 1
+    fn out_size(n: u32, config: MaxPool2DConfig) -> u32 {
+        return (n - config.kernel_size) / config.stride + 1;
+    }
+
+    // output[oy][ox] = max of the k x k window at (oy * stride, ox * stride);
+    // indices[oy][ox] = the flat input index that held it
+    fn forward(input: []const f32, height: u32, width: u32, config: MaxPool2DConfig, output: []f32, indices: []u32) -> void {
+        const oh = out_size(height, config);
+        const ow = out_size(width, config);
+        var oy : u32 = 0;
+        while (oy < oh) {
+            var ox : u32 = 0;
+            while (ox < ow) {
+                var best_index : u32 = (oy * config.stride) * width + ox * config.stride;
+                var ky : u32 = 0;
+                while (ky < config.kernel_size) {
+                    var kx : u32 = 0;
+                    while (kx < config.kernel_size) {
+                        const idx : u32 = (oy * config.stride + ky) * width + ox * config.stride + kx;
+                        if (input[idx] > input[best_index]) {
+                            best_index = idx;
+                        }
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                output[oy * ow + ox] = input[best_index];
+                indices[oy * ow + ox] = best_index;
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+    }
+
+    // grad_input[indices[o]] += grad_output[o]; every other input gets 0
+    fn backward(grad_output: []const f32, indices: []const u32, grad_input: []f32) -> void {
+        var i : usize = 0;
+        while (i < grad_input.len) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var o : usize = 0;
+        while (o < grad_output.len) {
+            grad_input[indices[o]] = grad_input[indices[o]] + grad_output[o];
+            o = o + 1;
+        }
+    }
+
+    fn cfg(kernel: u32, stride: u32) -> MaxPool2DConfig {
+        return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true };
+    }
+
+    // The 4 x 4 fixture
+    //    1  2  5  6
+    //    3  4  8  7
+    //    0 -1 -3 -2
+    //   -4  9 -6 -5
+    fn pool_at(kernel: u32, stride: u32, which: u8, index: usize) -> f32 {
+        const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0];
+        var output : [9]f32 = [0.0] ** 9;
+        var indices : [9]u32 = [0] ** 9;
+        forward(&input, 4, 4, cfg(kernel, stride), &output, &indices);
+        if (which == 0) {
+            return output[index];
+        }
+        return @as(f32, @floatFromInt(indices[index]));
+    }
+
+    // 2 x 2, stride 2, gradients (1, 2, 3, 4) for the four windows; grad_input[index]
+    fn backward_at(index: usize) -> f32 {
+        const input : [16]f32 = [1.0, 2.0, 5.0, 6.0, 3.0, 4.0, 8.0, 7.0, 0.0, -1.0, -3.0, -2.0, -4.0, 9.0, -6.0, -5.0];
+        var output : [4]f32 = [0.0] ** 4;
+        var indices : [4]u32 = [0] ** 4;
+        forward(&input, 4, 4, cfg(2, 2), &output, &indices);
+        const grad_output : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var grad_input : [16]f32 = [9.0] ** 16;
+        backward(&grad_output, &indices, &grad_input);
+        return grad_input[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // 2 x 2, stride 2: windows' maxima are 4, 8, 9, -2
+    test forward_basic_case
+        given first = pool_at(2, 2, 0, 0)
+        when last = pool_at(2, 2, 0, 3)
+        then first == 4.0 and pool_at(2, 2, 0, 1) == 8.0 and pool_at(2, 2, 0, 2) == 9.0 and last == -2.0
+
+    // The argmax indices: 4 at 5, 8 at 6, 9 at 13, -2 at 11
+    test forward_max_finding
+        given first = pool_at(2, 2, 1, 0)
+        when third = pool_at(2, 2, 1, 2)
+        then first == 5.0 and pool_at(2, 2, 1, 1) == 6.0 and third == 13.0 and pool_at(2, 2, 1, 3) == 11.0
+
+    // 3 x 3, stride 1 gives a 2 x 2 output whose windows overlap
+    test forward_overlapping_windows
+        given first = pool_at(3, 1, 0, 0)
+        when last = pool_at(3, 1, 0, 3)
+        then first == 8.0 and pool_at(3, 1, 0, 1) == 8.0 and pool_at(3, 1, 0, 2) == 9.0 and last == 9.0
+
+    test backward_basic_case
+        given at_max = backward_at(5)
+        when elsewhere = backward_at(0)
+        then at_max == 1.0 and elsewhere == 0.0
+
+    // Each window's gradient lands on its argmax only: the sum is conserved
+    test backward_gradient_propagation
+        given total = backward_at(5) + backward_at(6) + backward_at(13) + backward_at(11)
+        when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15)
+        then total == 10.0 and others == 0.0 and backward_at(13) == 3.0
+
+    invariant maxpool_output_size_formula
+        assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/mean-squared-error/card.png b/apps/website/public/ru/learn/mean-squared-error/card.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ac997fe0aa3d2b20d641c79a73ce419c7cf9b4 GIT binary patch literal 61504 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

hKD4_ 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 E09jm2DF6Tf literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/mean-squared-error/index.html b/apps/website/public/ru/learn/mean-squared-error/index.html new file mode 100644 index 0000000000..ccad6c6b03 --- /dev/null +++ b/apps/website/public/ru/learn/mean-squared-error/index.html @@ -0,0 +1,173 @@ + + + + + + +Среднеквадратичная ошибка: курс о нейросетях, урок 13 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Среднеквадратичная ошибка

+

Вы узнаете

Как MSE превращает каждый промах в одно число, почему она гоняется за большими ошибками и куда смотрит её градиент.

+

Функция потерь превращает все промахи модели в одно число, которое нужно уменьшать. Среднеквадратичная ошибка усредняет квадраты промахов: предсказания 1.5, 2 и 2 против целей 1, 2 и 3 стоят (0.25 + 0 + 1) / 3 = 0.4167. Из-за квадрата промах на 2 стоит в 4 раза больше промаха на 1, поэтому MSE гоняется за большими ошибками. Её градиент для каждого предсказания равен 2 (p - t) / n, здесь 0.333, 0 и -0.667: каждое предсказание толкается обратно к своей цели. Как функция одного предсказания потеря это парабола, чаша с одним дном. Спека mse_loss.t27 вычисляет потерю и градиент.

+

Попробовать

Передвиньте предсказание 2 на его цель и прочитайте потерю; затем ведите по чаше и найдите её дно.

+

Открыть интерактивный урок →

+
Mean squared error: how wrong a guess is, as one number
Mean squared error: how wrong a guess is, as one number ↗
+

Move three predictions against the targets 1, 2 and 3: the loss is the mean of the squared misses, its bowl is a parabola, and each gradient points its prediction back at the target.

+

specs/ml/loss/mse_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Penalizes large errors more heavily | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/mse_loss.tri: the port kept only
+// the first parameter and returned void, so forward computed a value and
+// threw it away, and every test asserted `result != undefined`.
+
+module MseLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    // reduction: "mean", "sum" or "none" (from the .tri). forward below is the
+    // .tri's mean; the field is carried, not yet read.
+    pub const MSELossConfig = struct {
+        reduction : []const u8,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(predictions, targets) -> mean((predictions - targets)^2); 0 for n = 0
+    fn forward(predictions: []const f32, targets: []const f32) -> f32 {
+        if (predictions.len == 0) {
+            return 0.0;
+        }
+        var sum_loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            const diff = predictions[i] - targets[i];
+            sum_loss = sum_loss + diff * diff;
+            i = i + 1;
+        }
+        return sum_loss / (predictions.len as f32);
+    }
+
+    // backward: grad_input[i] = 2 (predictions[i] - targets[i]) / n
+    fn backward(predictions: []const f32, targets: []const f32, grad_input: []f32) -> void {
+        if (predictions.len == 0) {
+            return;
+        }
+        const scale = 2.0 / (predictions.len as f32);
+        var i : usize = 0;
+        while (i < predictions.len) {
+            grad_input[i] = scale * (predictions[i] - targets[i]);
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    fn mse_at(p0: f32, p1: f32, p2: f32) -> f32 {
+        const predictions : [3]f32 = [p0, p1, p2];
+        const targets : [3]f32 = [1.0, 2.0, 3.0];
+        return forward(&predictions, &targets);
+    }
+
+    fn mse_grad_at(p0: f32, p1: f32, p2: f32, index: usize) -> f32 {
+        const predictions : [3]f32 = [p0, p1, p2];
+        const targets : [3]f32 = [1.0, 2.0, 3.0];
+        var grads : [3]f32 = [0.0] ** 3;
+        backward(&predictions, &targets, &grads);
+        return grads[index];
+    }
+
+    fn mse_empty() -> f32 {
+        const none : [0]f32 = [];
+        return forward(&none, &none);
+    }
+
+    test forward_zero_on_exact_match
+        given result = mse_at(1.0, 2.0, 3.0)
+        when also = mse_empty()
+        then result == 0.0 and also == 0.0
+
+    // errors (0.5, -1, 2): (0.25 + 1 + 4) / 3 = 1.75
+    test forward_basic_case
+        given result = mse_at(1.5, 1.0, 5.0)
+        when flipped = mse_at(0.5, 3.0, 1.0)
+        then @abs(result - 1.75) < 0.000001 and @abs(flipped - result) < 0.000001
+
+    test backward_matches_finite_difference
+        given slope = (mse_at(1.5, 1.001, 5.0) - mse_at(1.5, 0.999, 5.0)) / 0.002
+        when result = mse_grad_at(1.5, 1.0, 5.0, 1)
+        then @abs(result - slope) < 0.001 and @abs(result - (-2.0 / 3.0)) < 0.000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant mse_zero_at_target
+        assert mse_at(1.0, 2.0, 3.0) == 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/neural-networks/card.png b/apps/website/public/ru/learn/neural-networks/card.png new file mode 100644 index 0000000000000000000000000000000000000000..160e78f0afb0716a0e4977b11f9c81054fc724c1 GIT binary patch literal 63356 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

K5U5>}bo+wz0_IHQ9}}?MxC;1Ir^5Sr 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 A_W%F@ literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/neural-networks/index.html b/apps/website/public/ru/learn/neural-networks/index.html new file mode 100644 index 0000000000..cf00d6c5ae --- /dev/null +++ b/apps/website/public/ru/learn/neural-networks/index.html @@ -0,0 +1,72 @@ + + + + + + +Нейросети на t27: от одного нейрона до блока трансформера · t27 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+

Курс

+

Нейросети на t27: от одного нейрона до блока трансформера

+

Агенты этого проекта думают нейросетями, а здесь их части записаны спеками t27 с тестами, которые проверяет компилятор. Каждый виджет исполняет тела fn спеки из specs/ml, скомпилированные в WebAssembly: двигаете ползунок — отвечает спека.

+

Курс 10, 27 уроков, в каждом живой виджет и спека t27: функции активации, softmax и эмбеддинги, пулинг и пакетная нормализация, функции потерь, SGD, RMSProp и Adam, обратное распространение и XOR, рекуррентные ячейки, внимание, блок трансформера и PPO. Каждое число вычисляет скомпилированная спека.

+

Открыть интерактивный курс →

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/patches-of-a-picture/card.png b/apps/website/public/ru/learn/patches-of-a-picture/card.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b351d529af791c810da184e950dfcf8d962429 GIT binary patch literal 53684 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 Mq>@Cnn8~;Q3o>S^AOHXW literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/patches-of-a-picture/index.html b/apps/website/public/ru/learn/patches-of-a-picture/index.html new file mode 100644 index 0000000000..73bfebf141 --- /dev/null +++ b/apps/website/public/ru/learn/patches-of-a-picture/index.html @@ -0,0 +1,297 @@ + + + + + + +Участки картинки: курс о нейросетях, урок 10 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Участки картинки

+

Вы узнаете

Почему сети читают картинку по участкам и что даёт окно 2 x 2, усреднённое по каждому участку.

+

Картинка это сетка чисел, и сети читают её небольшими участками, чтобы один и тот же детектор работал в любом её месте. Здесь окно 2 x 2 шагает по 2 по картинке 4 x 4, где в клетке i лежит i, и каждый выход это среднее своего участка: 2.5, 4.5, 10.5 и 12.5. При обратном проходе градиент каждого выхода делится поровну на его 4 клетки. Это усредняющий пулинг: свёртка взвешивала бы 4 клетки выученным ядром, и её спека, t27#10612, ещё не слита. Спека avgpool2d_layer.t27 вычисляет оба прохода.

+

Попробовать

Нажмите на каждый участок и проверьте его среднее на глаз; затем включите градиент и прочитайте, что получает каждая клетка окна 4.

+

Открыть интерактивный урок →

+
Patches of a picture: a 2 x 2 window, averaged
Patches of a picture: a 2 x 2 window, averaged ↗
+

Tap a window on the 4 x 4 image: each output is the average of its 2 x 2 patch, two cells apart. Then switch to the gradient and see each output's blame shared out over its patch.

+

specs/ml/layers/avgpool2d_layer.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// 2D average pooling formula | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the kernel and stride were string constants typed `[]u32`, forward only
+// asserted that its input was non-empty, and the tests asserted `true` or
+// `result != undefined`. Average pooling now runs over one square H x H channel
+// with the default 2 x 2 window and stride 2 and no padding, and each test checks
+// numbers.
+
+module Avgpool2d;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_KERNEL : u32 = 2;
+    const DEFAULT_STRIDE : u32 = 2;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PoolConfig = struct {
+        kernel_size : []u32,
+        stride : []u32,
+        padding : []u32,
+    };
+
+    pub const PoolShape = struct {
+        batch : u32,
+        channels : u32,
+        height_in : u32,
+        width_in : u32,
+        height_out : u32,
+        width_out : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // Output side for an input side n: (n - k) / stride + 1, and 0 when no window fits
+    fn calc_output_size(height_in: u32) -> u32 {
+        if (height_in < DEFAULT_KERNEL) {
+            return 0;
+        }
+        return (height_in - DEFAULT_KERNEL) / DEFAULT_STRIDE + 1;
+    }
+
+    // output[oy][ox] = mean of the k x k window at (oy * stride, ox * stride) of a side x side
+    // input; returns the number of outputs written
+    fn forward(input: []const f32, side: u32, output: []f32) -> u32 {
+        const n = calc_output_size(side);
+        const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL));
+        var oy : u32 = 0;
+        while (oy < n) {
+            var ox : u32 = 0;
+            while (ox < n) {
+                var sum : f32 = 0.0;
+                var ky : u32 = 0;
+                while (ky < DEFAULT_KERNEL) {
+                    var kx : u32 = 0;
+                    while (kx < DEFAULT_KERNEL) {
+                        sum = sum + input[(oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx];
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                output[oy * n + ox] = sum / area;
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+        return n * n;
+    }
+
+    // backward: each window's gradient is shared equally by its k * k inputs
+    fn backward(grad_output: []const f32, side: u32, grad_input: []f32) -> void {
+        const n = calc_output_size(side);
+        const area : f32 = @as(f32, @floatFromInt(DEFAULT_KERNEL * DEFAULT_KERNEL));
+        var i : usize = 0;
+        while (i < grad_input.len) {
+            grad_input[i] = 0.0;
+            i = i + 1;
+        }
+        var oy : u32 = 0;
+        while (oy < n) {
+            var ox : u32 = 0;
+            while (ox < n) {
+                var ky : u32 = 0;
+                while (ky < DEFAULT_KERNEL) {
+                    var kx : u32 = 0;
+                    while (kx < DEFAULT_KERNEL) {
+                        const idx = (oy * DEFAULT_STRIDE + ky) * side + ox * DEFAULT_STRIDE + kx;
+                        grad_input[idx] = grad_input[idx] + grad_output[oy * n + ox] / area;
+                        kx = kx + 1;
+                    }
+                    ky = ky + 1;
+                }
+                ox = ox + 1;
+            }
+            oy = oy + 1;
+        }
+    }
+
+    // 4 x 4 input 0..15, row-major: windows average to 2.5, 4.5, 10.5, 12.5
+    fn pool4_at(index: usize) -> f32 {
+        var input : [16]f32 = [0.0] ** 16;
+        var i : usize = 0;
+        while (i < 16) {
+            input[i] = @as(f32, @floatFromInt(i));
+            i = i + 1;
+        }
+        var output : [4]f32 = [0.0] ** 4;
+        _ = forward(&input, 4, &output);
+        return output[index];
+    }
+
+    // forward over a 2 x 2 input (1, 2, 3, 4) or a 1 x 1 input (5); returns the outputs written
+    fn pool_count(side: u32) -> u32 {
+        const four : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        const one : [1]f32 = [5.0];
+        var output : [1]f32 = [-1.0];
+        if (side == 2) {
+            return forward(&four, 2, &output);
+        }
+        return forward(&one, 1, &output);
+    }
+
+    fn pool2_value() -> f32 {
+        const four : [4]f32 = [1.0, 2.0, 3.0, 4.0];
+        var output : [1]f32 = [-1.0];
+        _ = forward(&four, 2, &output);
+        return output[0];
+    }
+
+    fn backward4_at(index: usize) -> f32 {
+        const grad_output : [4]f32 = [4.0, 8.0, 12.0, 16.0];
+        var grad_input : [16]f32 = [9.0] ** 16;
+        backward(&grad_output, 4, &grad_input);
+        return grad_input[index];
+    }
+
+    fn valid_input() -> u32 {
+        return calc_output_size(4);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test calc_output_size_basic_case
+        given result = calc_output_size(4)
+        then result == 2
+
+    test calc_output_size_valid_input
+        given input = 10
+        when result = calc_output_size(input)
+        then result == 5
+
+    // A 1 x 1 input holds no 2 x 2 window
+    test calc_output_size_small_input
+        given input = 1
+        when result = calc_output_size(input)
+        then result == 0 and calc_output_size(2) == 1
+
+    test calc_output_size_large_input
+        given input = 1000
+        when result = calc_output_size(input)
+        then result == 500 and calc_output_size(1001) == 500
+
+    test forward_basic_case
+        given first = pool4_at(0)
+        when last = pool4_at(3)
+        then first == 2.5 and pool4_at(1) == 4.5 and pool4_at(2) == 10.5 and last == 12.5
+
+    // A 2 x 2 input is one window: the mean of 1, 2, 3, 4
+    test forward_non_empty_input
+        given count = pool_count(2)
+        when value = pool2_value()
+        then count == 1 and value == 2.5
+
+    test forward_single_element
+        given count = pool_count(1)
+        then count == 0
+
+    // Each of a window's 4 inputs gets a quarter of its gradient
+    test backward_spreads_the_gradient
+        given corner = backward4_at(0)
+        when last = backward4_at(15)
+        then corner == 1.0 and backward4_at(5) == 1.0 and backward4_at(2) == 2.0 and last == 4.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // kernel_size[i] >= 1
+    invariant avgpool2d_constraint_0
+        assert DEFAULT_KERNEL >= 1
+
+    // stride[i] >= 1
+    invariant avgpool2d_constraint_1
+        assert DEFAULT_STRIDE >= 1
+
+    // stride[i] <= kernel_size[i]: windows tile the input without gaps
+    invariant avgpool2d_constraint_2
+        assert DEFAULT_STRIDE <= DEFAULT_KERNEL
+
+    // name: avgpool_formula -- (n - k) / s + 1
+    invariant avgpool2d_constraint_3
+        assert valid_input() == 2
+
+    // "Zeiler & Fergus (2014) - Visualizing and Understanding Convolutional Networks": pooling halves each side
+    invariant avgpool2d_constraint_4
+        assert calc_output_size(8) == 4
+
+    // "He et al. (2016) - Deep Residual Learning for Image Recognition": a 7 x 7 map pools to 3 x 3
+    invariant avgpool2d_constraint_5
+        assert calc_output_size(7) == 3
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/positional-encoding/card.png b/apps/website/public/ru/learn/positional-encoding/card.png new file mode 100644 index 0000000000000000000000000000000000000000..f27ff3fb67d0ecde79e70358763d6cba976e7937 GIT binary patch literal 69013 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

41UX1n46u-)mB?(-xVM}u&w>Z; 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/positional-encoding/index.html b/apps/website/public/ru/learn/positional-encoding/index.html new file mode 100644 index 0000000000..b796c13faa --- /dev/null +++ b/apps/website/public/ru/learn/positional-encoding/index.html @@ -0,0 +1,163 @@ + + + + + + +Позиционное кодирование: курс о нейросетях, урок 25 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Позиционное кодирование

+

Вы узнаете

Как синусы и косинусы убывающих частот дают каждой позиции свой вектор и почему сдвиг это поворот.

+

Внимание видит свой вход как множество, поэтому порядок слов нужно к ним добавить. Синусоидальное кодирование даёт каждой позиции d чисел: sin и cos позиции, умноженной на частоту, которая от пары к паре падает в 10000^(2/d) раз. При d = 8 четыре пары поворачиваются на 1, 0.1, 0.01 и 0.001 радиана за позицию, как стрелки четырёх часов: позиция 5 читает -0.959, 0.284 в быстрой паре и 0.005, 1.000 в медленной. Длина каждой пары равна 1, и сдвиг на k позиций поворачивает каждую пару на свой постоянный угол. Спека positional_encoding.t27 вычисляет каждое значение.

+

Попробовать

Шагните с позиции 0 на 1 и посмотрите, какие часы двигаются; затем перейдите на 37 и найдите пару, которая всё ещё смотрит вверх.

+

Открыть интерактивный урок →

+
Positional encoding: how a transformer knows word order
Positional encoding: how a transformer knows word order ↗
+

Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows.

+

specs/ml/transformer/positional_encoding.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Uses sin/cos at different frequencies for each dimension | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward read an undeclared `d_model`, called `math::pow` / `math::sin` /
+// `math::cos`, computed each encoding into a local and dropped it, and grew the
+// frequency with the dimension where Vaswani et al. (2017) shrink it. It now
+// writes the sinusoidal encoding
+//   PE(pos, 2i) = sin(pos / 10000^(2i / d)),  PE(pos, 2i + 1) = cos(pos / 10000^(2i / d))
+// for each position into a positions x d_model buffer.
+
+module PositionalEnc;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_MAX_LEN : u32 = 2048;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PosEncConfig = struct {
+        d_model : u32,
+        max_len : u32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // 1 / 10000^(2i / d) = exp(-(2i / d) ln 10000)
+    fn inv_freq(pair: u32, d_model: u32) -> f32 {
+        return exp(-(@as(f32, @floatFromInt(2 * pair)) / @as(f32, @floatFromInt(d_model))) * log(@as(f32, 10000.0)));
+    }
+
+    fn forward(positions: []const u32, config: PosEncConfig, out: []f32) -> void {
+        var p : usize = 0;
+        while (p < positions.len) {
+            const pos : f32 = @as(f32, @floatFromInt(positions[p]));
+            var dim : u32 = 0;
+            while (dim < config.d_model) {
+                const angle = pos * inv_freq(dim / 2, config.d_model);
+                if (dim % 2 == 0) {
+                    out[p * config.d_model + dim] = sin(angle);
+                } else {
+                    out[p * config.d_model + dim] = cos(angle);
+                }
+                dim = dim + 1;
+            }
+            p = p + 1;
+        }
+    }
+
+    // PE(pos, dim) for d_model 8
+    fn pe(pos: u32, dim: usize) -> f32 {
+        const positions : [1]u32 = [pos];
+        var out : [8]f32 = [9.0] ** 8;
+        forward(&positions, PosEncConfig{ .d_model = 8, .max_len = DEFAULT_MAX_LEN }, &out);
+        return out[dim];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // pos 1, d 8: dims 0/1 use frequency 1, dims 2/3 use 1/10 (10000^(2/8) = 10)
+    test forward_basic_case
+        given s0 = pe(1, 0)
+        when s2 = pe(1, 2)
+        then @abs(s0 - 0.8414710) < 0.000001 and @abs(pe(1, 1) - 0.5403023) < 0.000001 and @abs(s2 - 0.0998334) < 0.000001 and @abs(pe(1, 3) - 0.9950042) < 0.000001
+
+    // Position 0 encodes as (0, 1, 0, 1, ...)
+    test forward_simple
+        given s = pe(0, 6)
+        when c = pe(0, 7)
+        then s == 0.0 and c == 1.0
+
+    // Each sin/cos pair lies on the unit circle
+    test forward_pairs_are_unit_vectors
+        given p = pe(37, 2) * pe(37, 2) + pe(37, 3) * pe(37, 3)
+        then @abs(p - 1.0) < 0.000001
+
+    invariant positional_encoding_max_len_is_positive
+        assert DEFAULT_MAX_LEN > 0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/ppo-and-the-reward/card.png b/apps/website/public/ru/learn/ppo-and-the-reward/card.png new file mode 100644 index 0000000000000000000000000000000000000000..4234979aec0454c3d1af7126c21fc86ed28475a9 GIT binary patch literal 57788 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/ppo-and-the-reward/index.html b/apps/website/public/ru/learn/ppo-and-the-reward/index.html new file mode 100644 index 0000000000..e846b27c3e --- /dev/null +++ b/apps/website/public/ru/learn/ppo-and-the-reward/index.html @@ -0,0 +1,272 @@ + + + + + + +PPO и награда: курс о нейросетях, урок 27 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

PPO и награда

+

Вы узнаете

Как PPO превращает награду в обновление политики и как его обрезка не даёт одному обновлению зайти слишком далеко.

+

Агент учится на награде, делая хорошие действия вероятнее. PPO измеряет изменение политики отношением r новой вероятности действия к старой и умножает его на преимущество A, насколько действие превзошло ожидание. Затем он обрезает: когда r ушло больше чем на eps в ту сторону, за которую награждает A, цель становится плоской. При r = 1.5, A = 1 и eps 0.2 сырое r A равно 1.5, но PPO засчитывает 1.2, так что один пакет не может далеко сдвинуть политику. На пакете спеки, отношения 1, 1.1 и 0.9 с преимуществами 2, 1.5 и 3, потеря политики равна -2.1167. Спека ppo_clip_loss.t27 её вычисляет.

+

Попробовать

Сделайте преимущество отрицательным и найдите, где кривая теперь становится плоской; затем расширьте eps до 0.5.

+

Открыть интерактивный урок →

+
PPO: how an agent learns from reward without lurching
PPO: how an agent learns from reward without lurching ↗
+

Drag the probability ratio of a new policy over the old: PPO's objective follows r times the advantage until r moves more than eps the rewarded way, then it goes flat and stops pulling.

+

specs/ml/rl/ppo_clip_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Probability ratio between policies | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written with `let x = if ... {}` and `for i in 0..n`, so it never compiled.
+// Three formulas were wrong, and their tests pinned the wrong values:
+// - compute_ratio returned log pi_new - log pi_old; the ratio is exp of that.
+// - clipped_surrogate returned clip(r) A; PPO's term is min(r A, clip(r) A), so
+//   r = 1.1 inside the clip range gives 2.2, not 2.4.
+// - policy_loss returned the surrogate itself, a quantity to MAXIMISE; as a loss
+//   added to the value and entropy losses it is minus the mean surrogate.
+// Each test now states the value PPO defines (Schulman et al., 2017).
+
+module PpoClipLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_CLIP_EPSILON : f32 = 0.2;
+    const DEFAULT_ENTROPY_COEF : f32 = 0.01;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const PPOClipConfig = struct {
+        clip_epsilon : f32,
+        entropy_coef : f32,
+        value_clip_coef : f32,
+    };
+
+    pub const PPOBatch = struct {
+        states : [][]f32,
+        actions : [][]f32,
+        old_log_probs : []f32,
+        advantages : []f32,
+        returns : []f32,
+        values : []f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // r = pi_new / pi_old = exp(log pi_new - log pi_old)
+    fn compute_ratio(new_log_prob: f32, old_log_prob: f32) -> f32 {
+        return exp(new_log_prob - old_log_prob);
+    }
+
+    // min(r A, clip(r, 1 - eps, 1 + eps) A)
+    fn clipped_surrogate(ratio: f32, advantage: f32, clip_epsilon: f32) -> f32 {
+        const clipped_ratio = @min(@max(ratio, 1.0 - clip_epsilon), 1.0 + clip_epsilon);
+        return @min(ratio * advantage, clipped_ratio * advantage);
+    }
+
+    // -mean_t min(r_t A_t, clip(r_t) A_t): the loss gradient descent minimises
+    fn policy_loss(ratios: []const f32, advantages: []const f32, clip_epsilon: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < ratios.len) {
+            total = total + clipped_surrogate(ratios[i], advantages[i], clip_epsilon);
+            i = i + 1;
+        }
+        return -total / @as(f32, @floatFromInt(ratios.len));
+    }
+
+    // -coef * mean entropy: lower loss for a more exploratory policy
+    fn entropy_loss(entropies: []const f32, entropy_coef: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < entropies.len) {
+            total = total + entropies[i];
+            i = i + 1;
+        }
+        return -entropy_coef * (total / @as(f32, @floatFromInt(entropies.len)));
+    }
+
+    // mean 0.5 (target - (old + clip(pred - old, -c, c)))^2
+    fn value_loss(predicted_values: []const f32, target_values: []const f32, old_values: []const f32, clip_coef: f32) -> f32 {
+        var total : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predicted_values.len) {
+            const diff = @min(@max(predicted_values[i] - old_values[i], -clip_coef), clip_coef);
+            const err = target_values[i] - (old_values[i] + diff);
+            total = total + 0.5 * err * err;
+            i = i + 1;
+        }
+        return total / @as(f32, @floatFromInt(predicted_values.len));
+    }
+
+    fn policy_loss_of(r0: f32, r1: f32, r2: f32) -> f32 {
+        const ratios : [3]f32 = [r0, r1, r2];
+        const advantages : [3]f32 = [2.0, 1.5, 3.0];
+        return policy_loss(&ratios, &advantages, DEFAULT_CLIP_EPSILON);
+    }
+
+    fn entropy_loss_of() -> f32 {
+        const entropies : [3]f32 = [0.5, 0.6, 0.4];
+        return entropy_loss(&entropies, DEFAULT_ENTROPY_COEF);
+    }
+
+    fn value_loss_of(p0: f32) -> f32 {
+        const predicted : [3]f32 = [p0, 2.0, 1.5];
+        const target : [3]f32 = [1.1, 2.1, 1.6];
+        const old : [3]f32 = [0.9, 1.9, 1.4];
+        return value_loss(&predicted, &target, &old, 0.2);
+    }
+
+    fn valid_input() -> f32 {
+        return DEFAULT_CLIP_EPSILON;
+    }
+
+    // total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) → f32
+    fn total_loss(policy_loss_value: f32, value_loss_value: f32, entropy_loss_value: f32, value_loss_coef: f32) -> f32 {
+        // Combine all loss components
+        return policy_loss_value + value_loss_coef * value_loss_value + entropy_loss_value;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test compute_ratio_basic_case
+        given 
+            new_log_prob = 0.5
+            old_log_prob = 0.3
+        when result = compute_ratio(new_log_prob, old_log_prob)
+        then @abs(result - 1.2214028) < 0.000001  // exp(0.2); the old `== 0.2` was the log ratio
+
+    test clipped_surrogate_basic_case
+        given 
+            ratio = 1.1
+            advantage = 2.0
+            clip_epsilon = 0.2
+        when result = clipped_surrogate(ratio, advantage, clip_epsilon)
+        then @abs(result - 1.1 * 2.0) < 0.000001  // inside [0.8, 1.2] the clip does nothing
+
+    test clipped_surrogate_clipping_case
+        given 
+            ratio = 1.5  // Above clip threshold of 1.2
+            advantage = 2.0
+            clip_epsilon = 0.2
+        when result = clipped_surrogate(ratio, advantage, clip_epsilon)
+        then @abs(result - 1.2 * 2.0) < 0.000001 and clipped_surrogate(0.5, -1.0, 0.2) == -0.8
+
+    // min(r A, clip(r) A) = (2.0, 1.65, 2.7): the loss is -mean = -2.1166667. The old `> 0` was
+    // the surrogate's sign; a ratio pushed past the clip earns nothing more.
+    test policy_loss_basic_case
+        given result = policy_loss_of(1.0, 1.1, 0.9)
+        when pushed = policy_loss_of(1.0, 1.1, 3.0)
+        then result < 0.0 and @abs(result + 2.1166667) < 0.000001 and @abs(pushed - policy_loss_of(1.0, 1.1, 1.2)) < 0.000001
+
+    test entropy_loss_basic_case
+        given result = entropy_loss_of()
+        then result < 0.0 and @abs(result + 0.005) < 0.0000001
+
+    test value_loss_basic_case
+        given result = value_loss_of(1.0)
+        when clipped = value_loss_of(5.0)
+        then result > 0.0 and @abs(result - 0.005) < 0.0000001 and @abs(clipped - value_loss_of(1.1)) < 0.0000001
+
+    test total_loss_basic_case
+        given 
+            policy_loss_value = 1.0
+            value_loss_value = 0.5
+            entropy_loss_value = -0.01
+            value_loss_coef = 0.5
+        when result = total_loss(policy_loss_value, value_loss_value, entropy_loss_value, value_loss_coef)
+        then @abs(result - (1.0 + 0.5 * 0.5 + (-0.01))) < 0.0000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // 0 < clip_epsilon <= 1 (typically 0.1-0.3)
+    invariant ppo_clip_loss_constraint_0
+        assert valid_input() > 0.0 and valid_input() <= 1.0
+
+    // entropy_coef >= 0
+    invariant ppo_clip_loss_constraint_1
+        assert DEFAULT_ENTROPY_COEF >= 0.0
+
+    // name: ppo_objective -- for A > 0 the surrogate stops growing at r = 1 + eps
+    invariant ppo_clip_loss_constraint_2
+        assert clipped_surrogate(5.0, 1.0, 0.2) == 1.2
+
+    // name: probability_ratio -- equal log-probabilities give r = 1
+    invariant ppo_clip_loss_constraint_3
+        assert compute_ratio(0.3, 0.3) == 1.0
+
+    // "Schulman et al. (2017) - Proximal Policy Optimization Algorithms, arXiv:1707.06347":
+    // for A < 0 the surrogate stops falling at r = 1 - eps
+    invariant ppo_clip_loss_constraint_4
+        assert clipped_surrogate(0.1, -1.0, 0.2) == -0.8
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/relu/card.png b/apps/website/public/ru/learn/relu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..519810c7ff98443afefa72675260a0611de63e90 GIT binary patch literal 61864 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/relu/index.html b/apps/website/public/ru/learn/relu/index.html new file mode 100644 index 0000000000..825676940d --- /dev/null +++ b/apps/website/public/ru/learn/relu/index.html @@ -0,0 +1,210 @@ + + + + + + +ReLU: оставить положительную часть: курс о нейросетях, урок 1 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

ReLU: оставить положительную часть

+

Вы узнаете

Что ReLU делает с положительным и с отрицательным входом и почему наклон 0 останавливает обучение нейрона.

+

Нейрон складывает взвешенные входы и пропускает сумму через функцию активации. ReLU из них самая простая, max(0, x): положительная сумма проходит без изменений, отрицательная становится 0. Её наклон равен 1 или 0, а наклон 0 означает нейрон, который перестал учиться: градиент через него назад не течёт. Утечка это исправляет: с наклоном 0.1 вход x = -2 даёт -0.2 и пропускает назад градиент 0.1. Спека relu_activation.t27 вычисляет обе кривые, которые рисует виджет.

+

Попробовать

Поставьте x на -2 и прочитайте наклон с утечкой и без неё; затем найдите наклон при x = 1.5.

+

Открыть интерактивный урок →

+
ReLU: what a neuron does with a negative number
ReLU: what a neuron does with a negative number ↗
+

Drag along the curve and watch ReLU pass every positive input and zero every negative one; give it a leaky slope and a little of the negative side gets through.

+

specs/ml/activation/relu_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// ReLU produces sparse gradients | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: the tests called forward and backward with one or two of their three or
+// four arguments, two asserted only `result != undefined`, and the invariants
+// asserted `true`. Each test now runs the functions on buffers and checks values.
+
+module Relu;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const ZERO : f32 = 0.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const ReLUConfig = struct {
+        negative_slope : f32,
+        inplace : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(input: []const f32, output: []f32, config: ReLUConfig) → void
+    fn forward(input: []const f32, output: []f32, config: ReLUConfig) -> void {
+        // Values at or below ZERO take the negative branch, values above ZERO pass through
+        // For negative_slope = 0.0, this gives max(0, x) behavior
+        var i : usize = 0;
+        while (i < input.len) : (i += 1) {
+            if (input[i] > ZERO) {
+                output[i] = input[i];  // Positive branch: identity
+            } else {
+                output[i] = input[i] * config.negative_slope;  // Negative branch: scaled
+            }
+        }
+    }
+
+    // backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) → void
+    fn backward(grad_output: []const f32, input: []const f32, grad_input: []f32, config: ReLUConfig) -> void {
+        // The gradient gate is on the forward input, not grad_output - this makes gradients sparse
+        var i : usize = 0;
+        while (i < input.len) : (i += 1) {
+            if (input[i] > ZERO) {
+                grad_input[i] = grad_output[i];  // Positive branch: identity gradient
+            } else {
+                grad_input[i] = grad_output[i] * config.negative_slope;  // Negative branch: scaled gradient
+            }
+        }
+    }
+
+    // Note: config.inplace is declared but currently unused by these functions.
+    // The buffers are separate parameters, so the aliasing case is not handled.
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    fn cfg(slope: f32) -> ReLUConfig {
+        return ReLUConfig{ .negative_slope = slope, .inplace = false };
+    }
+
+    // output[index] of forward over (a, b, c)
+    fn forward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 {
+        const input : [3]f32 = [a, b, c];
+        var output : [3]f32 = [9.0] ** 3;
+        forward(&input, &output, cfg(slope));
+        return output[index];
+    }
+
+    // grad_input[index] of backward over (a, b, c), every grad_output 1
+    fn backward_at(a: f32, b: f32, c: f32, slope: f32, index: usize) -> f32 {
+        const grad_output : [3]f32 = [1.0, 1.0, 1.0];
+        const input : [3]f32 = [a, b, c];
+        var grad_input : [3]f32 = [9.0] ** 3;
+        backward(&grad_output, &input, &grad_input, cfg(slope));
+        return grad_input[index];
+    }
+
+    // The shared fixture: one negative, zero, one positive.
+    fn valid_input() -> f32 {
+        return -2.0;
+    }
+
+    // max(0, x) on (-2, 0, 2)
+    test "forward_basic_case"
+        given negative = forward_at(-2.0, 0.0, 2.0, 0.0, 0)
+        when positive = forward_at(-2.0, 0.0, 2.0, 0.0, 2)
+        then negative == 0.0 and forward_at(-2.0, 0.0, 2.0, 0.0, 1) == 0.0 and positive == 2.0
+
+    test "forward_positive_identity"
+        given slope = 0.0
+        when first = forward_at(1.0, 2.0, 3.0, slope, 0)
+        then first == 1.0 and forward_at(1.0, 2.0, 3.0, slope, 1) == 2.0 and forward_at(1.0, 2.0, 3.0, slope, 2) == 3.0
+
+    test "forward_negative_scaling"
+        given slope = 0.5
+        when first = forward_at(-1.0, -2.0, -3.0, slope, 0)
+        then first == -0.5 and forward_at(-1.0, -2.0, -3.0, slope, 1) == -1.0 and forward_at(-1.0, -2.0, -3.0, slope, 2) == -1.5
+
+    test "forward_zero_negative_slope"
+        given slope = 0.0
+        when first = forward_at(-1.0, 0.0, 1.0, slope, 0)
+        then first == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 1) == 0.0 and forward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0
+
+    // grad_output * negative_slope for input <= ZERO (0 included), grad_output above it
+    test "backward_input_gate"
+        given slope = 0.5
+        when first = backward_at(-1.0, 0.0, 1.0, slope, 0)
+        then first == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 1) == 0.5 and backward_at(-1.0, 0.0, 1.0, slope, 2) == 1.0
+
+    // Plain ReLU: the gradient is 0 left of zero and passes through right of it
+    test "backward_basic_case"
+        given negative = backward_at(-2.0, 0.0, 2.0, 0.0, 0)
+        when positive = backward_at(-2.0, 0.0, 2.0, 0.0, 2)
+        then negative == 0.0 and positive == 1.0
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // input.len == output.len: forward writes every element of its buffer (none keeps the 9.0 fill)
+    invariant relu_constraint_0
+        assert forward_at(valid_input(), 0.0, 1.0, 0.0, 0) != 9.0 and forward_at(valid_input(), 0.0, 1.0, 0.0, 2) != 9.0
+
+    // A finite input gives a finite output: ReLU never exceeds its input's magnitude
+    invariant relu_constraint_1
+        assert @abs(forward_at(valid_input(), 0.0, 1.0, 0.5, 0)) <= @abs(valid_input())
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/rmsprop/card.png b/apps/website/public/ru/learn/rmsprop/card.png new file mode 100644 index 0000000000000000000000000000000000000000..d415522eace1341f7bdb86b565531d2012dcffc9 GIT binary patch literal 65587 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

x9UaA{Zgnaj< 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 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/rmsprop/index.html b/apps/website/public/ru/learn/rmsprop/index.html new file mode 100644 index 0000000000..1f38ad8cac --- /dev/null +++ b/apps/website/public/ru/learn/rmsprop/index.html @@ -0,0 +1,174 @@ + + + + + + +RMSProp: шаг без масштаба: курс о нейросетях, урок 17 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

RMSProp: шаг без масштаба

+

Вы узнаете

Как RMSProp делит каждый шаг на скользящий корень среднего квадрата, чтобы шаг больше не зависел от величины градиента.

+

Правильный размер шага зависит от величины градиента, а разные веса видят градиенты, отличающиеся в миллион раз. RMSProp хранит скользящее среднее квадрата градиента, кэш, и делит каждый шаг на его корень, поэтому у шага нет единиц: при постоянном градиенте 0.001, 0.5 или 1000 вес на шаге 1 сдвигается ровно на те же 0.0316 и идёт тем же путём, доходя до -0.0914 после 100 шагов при lr 0.01. Затухание задаёт, как медленно наполняется кэш: при 0.99 те же 100 шагов заканчиваются на -1.0261. Спека rmsprop.t27 вычисляет вес и кэш.

+

Попробовать

Переключайтесь между тремя градиентами и убедитесь, что линии не двигаются; затем поднимите затухание до 0.99.

+

Открыть интерактивный урок →

+
RMSProp: a step that does not care how big the gradient is
RMSProp: a step that does not care how big the gradient is ↗
+

Feed one weight a constant gradient of 0.001, 0.5 or 1000: RMSProp divides by the root of its running mean square, so all three walk the same path. Change the decay and the path bends.

+

specs/ml/optimizer/rmsprop.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// RMSprop optimizer with moving average of squared gradients | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/rmsprop.tri. The port kept only
+// `grad`, squared grad[0], and threw it away; the test read an undefined
+// default_input().
+
+module Rmsprop;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_DECAY : f32 = 0.9;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const RMSpropConfig = struct {
+        learning_rate : f32,
+        decay : f32,
+        epsilon : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // step(grad, param, cache, config) -> void, in place:
+    //   cache = decay * cache + (1 - decay) * grad^2
+    //   param -= lr * grad / (sqrt(cache) + epsilon)
+    // The .tri formula reads lr, decay and epsilon but its parameter list
+    // omits them; they come from config here.
+    fn step(grad: []const f32, param: []f32, cache: []f32, config: RMSpropConfig) -> void {
+        var i : usize = 0;
+        while (i < grad.len) {
+            const g = grad[i];
+            cache[i] = config.decay * cache[i] + (1.0 - config.decay) * g * g;
+            param[i] = param[i] - config.learning_rate * g / (@sqrt(cache[i]) + config.epsilon);
+            i = i + 1;
+        }
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    // run `steps` steps of constant gradient g on one parameter from 1.0
+    fn param_after(g: f32, steps: usize, decay: f32) -> f32 {
+        const grad : [1]f32 = [g];
+        var param : [1]f32 = [1.0];
+        var cache : [1]f32 = [0.0];
+        var k : usize = 0;
+        while (k < steps) {
+            step(&grad, &param, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = decay, .epsilon = 0.00000001 });
+            k = k + 1;
+        }
+        return param[0];
+    }
+
+    fn cache_after(g: f32, steps: usize) -> f32 {
+        const grad : [1]f32 = [g];
+        var param : [1]f32 = [1.0];
+        var cache : [1]f32 = [0.0];
+        var k : usize = 0;
+        while (k < steps) {
+            step(&grad, &param, &cache, RMSpropConfig{ .learning_rate = 0.01, .decay = DEFAULT_DECAY, .epsilon = 0.00000001 });
+            k = k + 1;
+        }
+        return cache[0];
+    }
+
+    // first step from cache 0: cache = 0.1 g^2, so the move is lr / sqrt(0.1)
+    // = 0.0316228 whatever the size of g
+    test first_step_is_scale_free
+        given small = param_after(0.001, 1, DEFAULT_DECAY)
+        when large = param_after(1000.0, 1, DEFAULT_DECAY)
+        then @abs(small - (1.0 - 0.0316228)) < 0.00001 and @abs(large - small) < 0.00001
+
+    // moving average of a constant: cache_n = (1 - 0.9^n) g^2
+    test cache_is_moving_average
+        given result = cache_after(2.0, 3)
+        when expected = (1.0 - 0.729) * 4.0
+        then @abs(result - expected) < 0.00001
+
+    test moves_against_the_gradient
+        given up = param_after(0.5, 2, DEFAULT_DECAY)
+        when down = param_after(-0.5, 2, DEFAULT_DECAY)
+        then up < 1.0 and down > 1.0 and @abs((1.0 - up) - (down - 1.0)) < 0.00001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant rmsprop_decay_in_unit_interval
+        assert DEFAULT_DECAY > 0.0 and DEFAULT_DECAY < 1.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/softmax-and-temperature/card.png b/apps/website/public/ru/learn/softmax-and-temperature/card.png new file mode 100644 index 0000000000000000000000000000000000000000..4e0f0049e40658c8704dcc11ff3a41b577f05613 GIT binary patch literal 56209 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 + + + + + +Softmax и температура: курс о нейросетях, урок 7 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Softmax и температура

+

Вы узнаете

Как softmax превращает оценки в вероятности с суммой один и что с ними делает температура.

+

Классификатор заканчивается одной оценкой на класс, и softmax превращает оценки в вероятности: exp каждой оценки, делённая на сумму всех. Оценки 1, 2 и 3 становятся 0.090, 0.245 и 0.665. Если сначала разделить оценки на температуру, меняется уверенность: при 0.5 верхняя оценка забирает 0.867, при 5 все три равны 0.27, 0.33 и 0.40. Языковая модель выбирает следующий токен именно отсюда, и настройка температуры чат-модели это и есть T. Спека softmax.t27 сначала вычитает наибольшую оценку, поэтому exp никогда не переполняется.

+

Попробовать

Охладите температуру до 0.1 и прочитайте три вероятности; затем сделайте ничью и нагрейте её.

+

Открыть интерактивный урок →

+
Softmax: how a network turns scores into a choice
Softmax: how a network turns scores into a choice ↗
+

Move three scores and the temperature: softmax turns them into probabilities that sum to one. Cool it and the top score takes almost everything; heat it and the choice evens out.

+

specs/ml/activation/softmax.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Control sharpness of distribution | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: written with `range` and `math::exp`, which no spec declares, so no test
+// ever ran. backward was also wrong: it used only the Jacobian's diagonal,
+// p_i (1 - p_i), and dropped the -p_i p_j terms. It is now the full product
+// grad_input_i = p_i (g_i - sum_j g_j p_j) / temperature.
+
+module Softmax;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const ZERO : f32 = 0.0;
+    const ONE : f32 = 1.0;
+    const MIN_TEMP : f32 = 0.001;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SoftmaxConfig = struct {
+        temperature : f32,
+        axis : u32,
+        stable : bool,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // output_i = exp((x_i - max) / T) / sum_j exp((x_j - max) / T); subtracting the max keeps exp finite
+    fn forward(logits: []const f32, output: []f32, config: SoftmaxConfig) -> void {
+        var max_val : f32 = logits[0];
+        var i : usize = 0;
+        while (i < logits.len) {
+            if (logits[i] > max_val) {
+                max_val = logits[i];
+            }
+            i = i + 1;
+        }
+        var sum : f32 = ZERO;
+        i = 0;
+        while (i < logits.len) {
+            output[i] = exp((logits[i] - max_val) / config.temperature);
+            sum = sum + output[i];
+            i = i + 1;
+        }
+        i = 0;
+        while (i < logits.len) {
+            output[i] = output[i] / sum;
+            i = i + 1;
+        }
+    }
+
+    // Vector-Jacobian product: grad_input_i = p_i (g_i - sum_j g_j p_j) / T
+    fn backward(grad_output: []const f32, probabilities: []const f32, grad_input: []f32, config: SoftmaxConfig) -> void {
+        var dot : f32 = ZERO;
+        var i : usize = 0;
+        while (i < grad_output.len) {
+            dot = dot + grad_output[i] * probabilities[i];
+            i = i + 1;
+        }
+        i = 0;
+        while (i < grad_output.len) {
+            grad_input[i] = probabilities[i] * (grad_output[i] - dot) / config.temperature;
+            i = i + 1;
+        }
+    }
+
+    fn cfg(temperature: f32) -> SoftmaxConfig {
+        return SoftmaxConfig{ .temperature = temperature, .axis = 0, .stable = true };
+    }
+
+    // output[index] of softmax over (a, b, c)
+    fn softmax_at(a: f32, b: f32, c: f32, temperature: f32, index: usize) -> f32 {
+        const logits : [3]f32 = [a, b, c];
+        var output : [3]f32 = [0.0] ** 3;
+        forward(&logits, &output, cfg(temperature));
+        return output[index];
+    }
+
+    // grad_input[index] for grad_output (0.1, 0.2, 0.3) at probabilities (0.2, 0.3, 0.5)
+    fn backward_at(index: usize) -> f32 {
+        const grad_output : [3]f32 = [0.1, 0.2, 0.3];
+        const probabilities : [3]f32 = [0.2, 0.3, 0.5];
+        var grad_input : [3]f32 = [0.0] ** 3;
+        backward(&grad_output, &probabilities, &grad_input, cfg(1.0));
+        return grad_input[index];
+    }
+
+    // L = sum_i w_i softmax(x)_i with w = (0.1, 0.2, 0.3): the loss whose gradient backward computes
+    fn weighted(a: f32, b: f32, c: f32) -> f32 {
+        return 0.1 * softmax_at(a, b, c, 1.0, 0) + 0.2 * softmax_at(a, b, c, 1.0, 1) + 0.3 * softmax_at(a, b, c, 1.0, 2);
+    }
+
+    fn grad_at(a: f32, b: f32, c: f32, index: usize) -> f32 {
+        const grad_output : [3]f32 = [0.1, 0.2, 0.3];
+        var probabilities : [3]f32 = [0.0] ** 3;
+        const logits : [3]f32 = [a, b, c];
+        forward(&logits, &probabilities, cfg(1.0));
+        var grad_input : [3]f32 = [0.0] ** 3;
+        backward(&grad_output, &probabilities, &grad_input, cfg(1.0));
+        return grad_input[index];
+    }
+
+    fn valid_input() -> f32 {
+        return 3.0;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // softmax(1, 2, 3) = (0.0900306, 0.2447285, 0.6652410)
+    test "forward_basic_case"
+        given p0 = softmax_at(1.0, 2.0, 3.0, 1.0, 0)
+        when p2 = softmax_at(1.0, 2.0, 3.0, 1.0, 2)
+        then p0 > 0.0 and softmax_at(1.0, 2.0, 3.0, 1.0, 1) > 0.0 and p2 > 0.0 and @abs(p0 + softmax_at(1.0, 2.0, 3.0, 1.0, 1) + p2 - 1.0) < 0.0001 and @abs(p0 - 0.0900306) < 0.000001 and @abs(p2 - 0.6652410) < 0.000001
+
+    // Subtracting the max: logits of 1000 do not overflow exp
+    test "forward_large_logits_stay_finite"
+        given p = softmax_at(1000.0, 1000.0, 1000.0, 1.0, 1)
+        then @abs(p - 1.0 / 3.0) < 0.000001
+
+    // A higher temperature flattens the distribution toward uniform
+    test "forward_temperature_flattens"
+        given sharp = softmax_at(1.0, 2.0, 3.0, 1.0, 2)
+        when flat = softmax_at(1.0, 2.0, 3.0, 10.0, 2)
+        then flat < sharp and flat > 1.0 / 3.0
+
+    // dot = 0.23: grad = (0.2 (0.1 - 0.23), 0.3 (0.2 - 0.23), 0.5 (0.3 - 0.23)) = (-0.026, -0.009, 0.035)
+    test "backward_basic_case"
+        given g0 = backward_at(0)
+        when g2 = backward_at(2)
+        then g0 != 0.0 and backward_at(1) != 0.0 and g2 != 0.0 and @abs(g0 - (-0.026)) < 0.000001 and @abs(backward_at(1) - (-0.009)) < 0.000001 and @abs(g2 - 0.035) < 0.000001
+
+    // The gradient of a function of probabilities that sum to 1 sums to 0
+    test "backward_sums_to_zero"
+        given total = backward_at(0) + backward_at(1) + backward_at(2)
+        then @abs(total) < 0.0000001
+
+    test "backward_matches_finite_difference"
+        given slope = (weighted(1.0, 2.0 + 0.001, 3.0) - weighted(1.0, 2.0 - 0.001, 3.0)) / 0.002
+        when result = grad_at(1.0, 2.0, 3.0, 1)
+        then @abs(result - slope) < 0.0005
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // logits.size() == output.size(): the first and last element are both probabilities
+    invariant softmax_constraint_0
+        assert softmax_at(1.0, 2.0, valid_input(), 1.0, 0) >= 0.0 and softmax_at(1.0, 2.0, valid_input(), 1.0, 2) >= 0.0
+
+    // config.temperature >= MIN_TEMP
+    invariant softmax_constraint_1
+        assert cfg(1.0).temperature >= MIN_TEMP
+
+    // sum(output) = 1.0 within floating precision
+    invariant softmax_constraint_2
+        assert @abs(softmax_at(1.0, 2.0, valid_input(), 1.0, 0) + softmax_at(1.0, 2.0, valid_input(), 1.0, 1) + softmax_at(1.0, 2.0, valid_input(), 1.0, 2) - 1.0) < 0.0001
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/swish-and-silu/card.png b/apps/website/public/ru/learn/swish-and-silu/card.png new file mode 100644 index 0000000000000000000000000000000000000000..6aeefe19cadd4aebda67ce23a07f019322146a0d GIT binary patch literal 58016 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 UUr!gOBN>Tz@;r6dA^6&V06HSrC;$Ke literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/swish-and-silu/index.html b/apps/website/public/ru/learn/swish-and-silu/index.html new file mode 100644 index 0000000000..879b8c76d1 --- /dev/null +++ b/apps/website/public/ru/learn/swish-and-silu/index.html @@ -0,0 +1,210 @@ + + + + + + +Swish и SiLU: курс о нейросетях, урок 5 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
t27.aiEnglish
+
+ +

Swish и SiLU

+

Вы узнаете

Как x, умноженный на sigmoid(beta x), открывает сам себя и как один параметр переводит его от гладкой кривой к ReLU.

+

Swish это x, умноженный на sigmoid(beta x): нейрон, который сам себе вентиль. При beta 1 он называется SiLU, и его нижняя точка -0.2785 около x = -1.28. Увеличьте beta, и вентиль становится резче: при beta 8 кривая это ReLU со скруглёнными углами, при beta 0.5 пологий склон через ноль. Один параметр переводит нейрон от гладкой кривой к переключателю, и сеть может его выучить. Спека silu_swish_activation.t27 вычисляет кривую и её наклон при любом beta, а также свой пакет при -2, 0 и 2: -0.238, 0 и 1.762.

+

Попробовать

Держите x на -1.28 и поднимайте beta от 1 до 8; затем найдите beta, при котором провал на этом масштабе исчезает.

+

Открыть интерактивный урок →

+
Swish: one knob between a smooth curve and ReLU
Swish: one knob between a smooth curve and ReLU ↗
+

Drag along x times sigmoid(beta x). At beta 1 it is SiLU, with its dip of -0.28; turn beta up and the curve closes on ReLU, turn it down and it flattens toward x / 2.

+

specs/ml/activation/silu_swish_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// SiLU derivative | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: forward_batch returned its input unchanged, beta was never read, and the
+// invariants asserted `true` over an undeclared `valid_input`. SiLU is now
+// x * sigmoid(beta * x) (Swish; beta = 1 is SiLU) on scalars and in place on slices.
+
+module SiluSwish;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 1. Constants
+    // ═══════════════════════════════════════════════════════════
+
+    const DEFAULT_BETA : f32 = 1.0;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SiLUConfig = struct {
+        beta : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // sigmoid(z) = 1 / (1 + exp(-z))
+    fn sigmoid(z: f32) -> f32 {
+        return 1.0 / (1.0 + exp(-z));
+    }
+
+    // Swish(x) = x * sigmoid(beta * x); beta = 1 is SiLU
+    fn forward(x: f32, beta: f32) -> f32 {
+        return x * sigmoid(beta * x);
+    }
+
+    // forward on each element IN PLACE; returns the same slice
+    fn forward_batch(input: []f32, beta: f32) -> []f32 {
+        var i : usize = 0;
+        while (i < input.len) {
+            input[i] = forward(input[i], beta);
+            i = i + 1;
+        }
+        return input;
+    }
+
+    // d/dx x sigmoid(beta x) = s + beta x s (1 - s), s = sigmoid(beta x)
+    fn derivative(x: f32, beta: f32) -> f32 {
+        const s = sigmoid(beta * x);
+        return s + beta * x * s * (1.0 - s);
+    }
+
+    fn batch_at(a: f32, b: f32, c: f32, index: usize) -> f32 {
+        var input : [3]f32 = [a, b, c];
+        const output = forward_batch(&input, DEFAULT_BETA);
+        return output[index];
+    }
+
+    fn valid_input() -> f32 {
+        return 2.0;
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    test "forward_basic_case"
+        given input = 0.0, beta = 1.0
+        when result = forward(input, beta)
+        then result == 0.0  // SiLU(0) = 0 * sigmoid(0) = 0
+
+    test "forward_positive_case"
+        given input = 1.0, beta = 1.0
+        when result = forward(input, beta)
+        then result > 0.0  // SiLU(1) = 1 * sigmoid(1) > 0
+
+    test "forward_negative_case"
+        given input = -1.0, beta = 1.0
+        when result = forward(input, beta)
+        then result < 0.0  // SiLU(-1) = -1 * sigmoid(-1) < 0
+
+    test "forward_batch_basic_case"
+        given beta = 1.0
+        when result = batch_at(1.0, 2.0, 3.0, 2)
+        then @abs(result - forward(3.0, beta)) < 0.0000001 and @abs(batch_at(1.0, 2.0, 3.0, 0) - 0.7310586) < 0.000001
+
+    test "forward_batch_zero_case"
+        given beta = 1.0
+        when result = batch_at(0.0, 0.0, 0.0, 0)
+        then result == 0.0 and batch_at(0.0, 0.0, 0.0, 1) == 0.0 and batch_at(0.0, 0.0, 0.0, 2) == 0.0  // SiLU(0) = 0
+
+    test "derivative_basic_case"
+        given input = 0.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU'(0) = sigmoid(0) + 0 * sigmoid(0) * (1 - sigmoid(0)) = sigmoid(0) > 0
+
+    test "derivative_positive_case"
+        given input = 1.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU derivative should be positive for positive inputs
+
+    test "derivative_negative_case"
+        given input = -1.0, beta = 1.0
+        when result = derivative(input, beta)
+        then result > 0.0  // SiLU derivative should be positive for negative inputs too
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants (from .tri constraints)
+    // ═══════════════════════════════════════════════════════════
+
+    // beta > 0
+    invariant silu_swish_constraint_0
+        assert DEFAULT_BETA > 0.0
+
+    // name: silu_formula -- x * sigmoid(x), so SiLU(x) - SiLU(-x) = x
+    invariant silu_swish_constraint_1
+        assert @abs(forward(valid_input(), DEFAULT_BETA) - forward(-valid_input(), DEFAULT_BETA) - valid_input()) < 0.000001
+
+    // name: derivative -- sigmoid(0) = 0.5 at the origin
+    invariant silu_swish_constraint_2
+        assert derivative(0.0, DEFAULT_BETA) == 0.5
+
+    // "Elfwing et al. (2017) - Sigmoid-Weighted Linear Units for Neural Network Function Approximation":
+    // SiLU dips below zero left of the origin
+    invariant silu_swish_constraint_3
+        assert forward(-valid_input(), DEFAULT_BETA) < 0.0
+
+    // "Ramachandran et al. (2017) - Searching for Activation Functions (Swish)": a large beta
+    // approaches ReLU
+    invariant silu_swish_constraint_4
+        assert @abs(forward(valid_input(), 50.0) - valid_input()) < 0.000001
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/tanh-and-saturation/card.png b/apps/website/public/ru/learn/tanh-and-saturation/card.png new file mode 100644 index 0000000000000000000000000000000000000000..964dc477da0211cc0c5bc5af92b5ee4746c69325 GIT binary patch literal 50337 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 B96bO4 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/tanh-and-saturation/index.html b/apps/website/public/ru/learn/tanh-and-saturation/index.html new file mode 100644 index 0000000000..f3d83594ee --- /dev/null +++ b/apps/website/public/ru/learn/tanh-and-saturation/index.html @@ -0,0 +1,171 @@ + + + + + + +tanh и насыщение: курс о нейросетях, урок 3 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

tanh и насыщение

+

Вы узнаете

Почему tanh центрирована на нуле и где её наклон падает так низко, что нейрон перестаёт учиться.

+

tanh это сигмоида, растянутая на -1..1 и центрированная на 0, поэтому слой нейронов tanh передаёт дальше значения со средним около нуля, а её наклон в центре достигает 1. Она тоже насыщается: при 2.5 выход 0.9866, а наклон всего 0.0266. Красная полоса отмечает все входы, где наклон меньше 0.1, дальше примерно 1.8 в обе стороны, и нейрон, чьи входы живут там, почти не учится. Спека tanh_activation.t27 вычисляет кривую, наклон и свой пакет, tanh от 0, 1 и 2: 0, 0.762 и 0.964.

+

Попробовать

Тяните x, пока не начнётся полоса, и прочитайте наклон там; затем сравните наклон в 0 и при 2.5.

+

Открыть интерактивный урок →

+
tanh: where a neuron stops learning
tanh: where a neuron stops learning ↗
+

Drag along tanh: it is centred on zero, and where it flattens out its slope drops under 0.1. The red band shows every input where the gradient has all but stopped.

+

specs/ml/activation/tanh_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative (can compute from output) | φ² + 1/φ² = 3 | TRINITY
+
+// #8980: `math::exp` named a module this spec never imports, and
+// forward_batch allocated with `[]f32{input.len}`. tanh is now computed in the
+// form that cannot overflow: exp(2|x|) reaches inf in f32 at |x| = 45, and
+// inf / inf is NaN.
+
+module Tanh;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const TanhConfig = struct {
+        none : void,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // tanh(x) = (1 - e^(-2|x|)) / (1 + e^(-2|x|)), with the sign of x
+    fn forward(x: f32) -> f32 {
+        if (x < 0.0) {
+            return -forward(-x);
+        }
+        const t = exp(-2.0 * x);
+        return (1.0 - t) / (1.0 + t);
+    }
+
+    // forward_batch: output[i] = tanh(input[i])
+    fn forward_batch(input: []const f32, output: []f32) -> void {
+        var i : usize = 0;
+        while (i < input.len) {
+            output[i] = forward(input[i]);
+            i = i + 1;
+        }
+    }
+
+    // tanh'(x) = 1 - tanh(x)^2
+    fn derivative(x: f32) -> f32 {
+        const tanh_x = forward(x);
+        return 1.0 - (tanh_x * tanh_x);
+    }
+
+    // Given y = tanh(x), the derivative is 1 - y^2
+    fn derivative_from_output(tanh_x: f32) -> f32 {
+        return 1.0 - (tanh_x * tanh_x);
+    }
+
+    fn batch_at(index: usize) -> f32 {
+        const input : [3]f32 = [0.0, 1.0, 2.0];
+        var output : [3]f32 = [0.0] ** 3;
+        forward_batch(&input, &output);
+        return output[index];
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // tanh(0) = 0, tanh(1) = 0.7615942, tanh is odd
+    test forward_basic_case
+        given input = 0.0
+        when result = forward(input)
+        then result == 0.0 and @abs(forward(1.0) - 0.7615942) < 0.000001 and forward(-1.0) == -forward(1.0)
+
+    // exp(2x) is inf in f32 here; the stable form still gives 1, not NaN
+    test forward_saturates_without_overflow
+        given input = 100.0
+        when result = forward(input)
+        then result == 1.0 and forward(-100.0) == -1.0
+
+    test forward_batch_basic_case
+        given first = batch_at(0)
+        when second = batch_at(1)
+        then first == 0.0 and second > 0.0 and second < 1.0 and batch_at(2) > second
+
+    test derivative_basic_case
+        given input = 0.0
+        when result = derivative(input)
+        then result == 1.0
+
+    test derivative_from_output_basic_case
+        given input = 0.5
+        when tanh_result = forward(input)
+        then derivative_from_output(tanh_result) > 0.0 and derivative_from_output(tanh_result) < 1.0 and derivative_from_output(tanh_result) == derivative(input)
+
+    test derivative_matches_finite_difference
+        given slope = (forward(0.5 + 0.001) - forward(0.5 - 0.001)) / 0.002
+        when result = derivative(0.5)
+        then @abs(result - slope) < 0.001
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/the-huber-loss/card.png b/apps/website/public/ru/learn/the-huber-loss/card.png new file mode 100644 index 0000000000000000000000000000000000000000..2e61ac0bb3421973f75971b7d7f1c720cddba1d0 GIT binary patch literal 65847 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%0Aj+ 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 PBRER(YI5bWW}*KJg}xr0 literal 0 HcmV?d00001 diff --git a/apps/website/public/ru/learn/the-huber-loss/index.html b/apps/website/public/ru/learn/the-huber-loss/index.html new file mode 100644 index 0000000000..7c7a3323ca --- /dev/null +++ b/apps/website/public/ru/learn/the-huber-loss/index.html @@ -0,0 +1,169 @@ + + + + + + +Функция Хьюбера: курс о нейросетях, урок 15 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

Функция Хьюбера

+

Вы узнаете

Как функция Хьюбера обходится с малой ошибкой как с квадратичной, а с большой линейно, чтобы выбросы тянули слабее.

+

Квадратичная ошибка позволяет одному выбросу всё решать: ошибка 3 стоит 4.5 как половина своего квадрата, столько же, сколько 36 ошибок по 0.5. Функция Хьюбера равна половине квадрата, пока |e| не больше delta, а дальше растёт только линейно, delta |e| - delta^2 / 2, так что при delta 1 та же ошибка стоит 2.5. Два куска сходятся с одинаковым значением и наклоном, и градиент никогда не превышает delta: далёкая точка тянет модель с ограниченной силой. Для пары ошибок спеки 0.5 и 3 среднее равно 1.3125 против 2.3125 для половины квадрата. Спека huber_loss.t27 вычисляет обе.

+

Попробовать

Поставьте delta на 0.5 и тяните ошибку к 3; затем найдите, где две кривые расходятся.

+

Открыть интерактивный урок →

+
Huber loss: a loss that does not panic at an outlier
Huber loss: a loss that does not panic at an outlier ↗
+

Drag the error along: Huber is half its square inside delta and only grows linearly outside, so one wild miss pulls on the model with a bounded force. The dashed curve is the pure square.

+

specs/ml/loss/huber_loss.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Threshold where loss changes from quadratic to linear | φ² + 1/φ² = 3 | TRINITY
+// Restored 2026-10-05 from trinity specs/algo/huber_loss.tri: the port kept only
+// the first parameter and returned void, so forward computed a value and
+// threw it away, and every test asserted `result != undefined`.
+
+module HuberLoss;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const HuberLossConfig = struct {
+        delta : f32,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // per element e = prediction - target:
+    //   |e| <= delta: 0.5 e^2      else: delta |e| - 0.5 delta^2
+    fn element_loss(e: f32, delta: f32) -> f32 {
+        const a = @abs(e);
+        if (a <= delta) {
+            return 0.5 * e * e;
+        }
+        return delta * a - 0.5 * delta * delta;
+    }
+
+    // forward(predictions, targets, delta) -> f32. The .tri gives the
+    // per-element formula only; this returns the MEAN over elements
+    // (PyTorch HuberLoss default reduction). 0 for n = 0.
+    fn forward(predictions: []const f32, targets: []const f32, delta: f32) -> f32 {
+        if (predictions.len == 0) {
+            return 0.0;
+        }
+        var sum_loss : f32 = 0.0;
+        var i : usize = 0;
+        while (i < predictions.len) {
+            sum_loss = sum_loss + element_loss(predictions[i] - targets[i], delta);
+            i = i + 1;
+        }
+        return sum_loss / (predictions.len as f32);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests
+    // ═══════════════════════════════════════════════════════════
+
+    fn huber_one(e: f32, delta: f32) -> f32 {
+        const predictions : [1]f32 = [e];
+        const targets : [1]f32 = [0.0];
+        return forward(&predictions, &targets, delta);
+    }
+
+    test quadratic_inside_delta
+        given result = huber_one(0.5, 1.0)
+        when negative = huber_one(-0.5, 1.0)
+        then @abs(result - 0.125) < 0.000001 and result == negative
+
+    // delta |e| - delta^2 / 2 = 3 - 0.5
+    test linear_outside_delta
+        given result = huber_one(3.0, 1.0)
+        when wide = huber_one(3.0, 2.0)
+        then @abs(result - 2.5) < 0.000001 and @abs(wide - 4.0) < 0.000001
+
+    // the two pieces meet with equal value and slope at |e| = delta
+    test continuous_at_delta
+        given below = huber_one(0.999, 1.0)
+        when above = huber_one(1.001, 1.0)
+        then @abs(above - below - 0.002) < 0.0001
+
+    // mean of (0.125, 2.5) over two elements
+    fn huber_two(e0: f32, e1: f32, delta: f32) -> f32 {
+        const predictions : [2]f32 = [e0 + 1.0, e1 + 1.0];
+        const targets : [2]f32 = [1.0, 1.0];
+        return forward(&predictions, &targets, delta);
+    }
+
+    test forward_mean
+        given result = huber_two(0.5, 3.0, 1.0)
+        when expected = 1.3125
+        then @abs(result - expected) < 0.000001
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Invariants
+    // ═══════════════════════════════════════════════════════════
+
+    invariant huber_zero_at_target
+        assert huber_one(0.0, 1.0) == 0.0
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/public/ru/learn/the-sigmoid/card.png b/apps/website/public/ru/learn/the-sigmoid/card.png new file mode 100644 index 0000000000000000000000000000000000000000..b42381ca1568746eac325d2ccd30600caefadb8a GIT binary patch literal 57067 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

qL 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 z%0A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 + + + + + +Сигмоида: число в вероятность: курс о нейросетях, урок 2 из 27 + + + + + + + + + + + + + + + + + + + + + + + + + + + +

t27.aiEnglish
+
+ +

Сигмоида: число в вероятность

+

Вы узнаете

Как сигмоида переводит любой вход в вероятность и почему её наклон мешает глубоким сетям.

+

Сигмоида 1 / (1 + e^-x) сжимает всю числовую прямую в отрезок от 0 до 1, поэтому её читают как вероятность: 2 превращается в 0.8808, а -4 в 0.018. Её наклон равен s (1 - s) и считается по самому выходу s; он наибольший в 0, где равен 0.25, а при x = 8 равен 0.000335. Градиент, который идёт назад через стопку сигмоид, на каждой умножается не больше чем на 0.25, поэтому глубокие сети на сигмоидах учились медленно. Спека sigmoid_activation.t27 вычисляет кривую и наклон.

+

Попробовать

Найдите вход, при котором вероятность равна 0.5; затем перетащите к 6 и посмотрите, как мало осталось наклона.

+

Открыть интерактивный урок →

+
Sigmoid: turn any number into a probability
Sigmoid: turn any number into a probability ↗
+

Drag along the S-curve: every input lands between 0 and 1, and the slope peaks at 0.25 in the middle and dies away at both ends.

+

specs/ml/activation/sigmoid_activation.t27

// SPDX-License-Identifier: Apache-2.0
+// t27/specs/
+// Derivative (compute from output) | φ² + 1/φ² = 3 | TRINITY
+
+module Sigmoid;
+    use base::types;
+    use math::constants;
+
+    // ═══════════════════════════════════════════════════════════
+    // 2. Types
+    // ═══════════════════════════════════════════════════════════
+
+    pub const SigmoidConfig = struct {
+        none : void,
+    };
+
+    // ═══════════════════════════════════════════════════════════
+    // 3. Core Functions
+    // ═══════════════════════════════════════════════════════════
+
+    // forward(x: f32) → f32
+    fn forward(x: f32) -> f32 {
+        // Numerically stable split to avoid overflow:
+        // For x >= 0: 1 / (1 + exp(-x))
+        // For x < 0: exp(x) / (1 + exp(x))
+        // Both branches are mathematically equivalent but the second avoids exp(large positive)
+        if (x >= 0.0) {
+            return 1.0 / (1.0 + @exp(-x));
+        } else {
+            return @exp(x) / (1.0 + @exp(x));
+        }
+    }
+
+    // forward_batch(input: []f32) → []f32
+    fn forward_batch(input: []f32) -> []f32 {
+        // In-place map over input: alias input and return it
+        // This is safe because we're only reading from input and writing to the same locations
+        let i = 0;
+        while (i < input.len) {
+            input[i] = forward(input[i]);
+            i += 1;
+        }
+        return input;
+    }
+
+    // derivative(sigmoid_x: f32) → f32
+    fn derivative(sigmoid_x: f32) -> f32 {
+        // Derivative computed from output: σ'(x) = σ(x) * (1 - σ(x))
+        return sigmoid_x * (1.0 - sigmoid_x);
+    }
+
+    // ═══════════════════════════════════════════════════════════
+    // TDD: Tests (from .tri behaviors)
+    // ═══════════════════════════════════════════════════════════
+
+    // #8980: through a function, so the check runs and is counted (it folded at compile
+    // time before, and the report counted it as a vacuous pass).
+    fn config_size() -> usize {
+        return @sizeOf(SigmoidConfig);
+    }
+
+    test sigmoid_has_no_tunable_parameter
+        given size = config_size()
+        then size == 0
+
+    // sigmoid_config_is_a_placeholder_not_an_empty_struct read std.meta.fields, which t27
+    // cannot lower; the parser discarded it. The test above already pins @sizeOf == 0.
+
+    test forward_at_zero_is_one_half
+        given y = forward(0.0)
+        then @abs(y - 0.5) < 1e-6
+
+    test forward_confined_to_unit_interval
+        given pos_large = forward(10.0)
+        given neg_large = forward(-10.0)
+        then (pos_large > 0.0) and (pos_large < 1.0) and (neg_large > 0.0) and (neg_large < 1.0)
+
+    test derivative_at_zero_is_maximum
+        given dy = derivative(forward(0.0))
+        then @abs(dy - 0.25) < 1e-6
+
+    test forward_batch_preserves_length
+        given input = []f32{0.0, 1.0, -1.0, 2.0, -2.0}
+        given result = forward_batch(input)
+        then result.len == input.len
+
+    // sigmoid(-x) = 1 - sigmoid(x); sigmoid(2) = 0.8807971
+    test forward_is_symmetric_about_one_half
+        given up = forward(2.0)
+        when down = forward(-2.0)
+        then @abs(up + down - 1.0) < 0.000001 and @abs(up - 0.8807971) < 0.000001
+
+    // The negative branch never computes exp(+x): no overflow at -100
+    test forward_far_left_is_zero_not_nan
+        given y = forward(-100.0)
+        then y >= 0.0 and y < 0.000001
+

Открыть спеку урока в плеере ↗

+ +

Все уроки

+ +
+ + + diff --git a/apps/website/scripts/course-from-spec.test.mjs b/apps/website/scripts/course-from-spec.test.mjs index 4a5ed9682f..0f14b9628e 100644 --- a/apps/website/scripts/course-from-spec.test.mjs +++ b/apps/website/scripts/course-from-spec.test.mjs @@ -119,7 +119,7 @@ test('a lesson in two courses fails the build: its page can show one', async () }) test('a course left out of the catalog fails the build', async () => { - await fails({ catalogText: replaced(inputs.catalogText, 'pub const COURSE_COUNT : u8 = 9;', 'pub const COURSE_COUNT : u8 = 10;') }, 'the_basics_come_first') + await fails({ catalogText: replaced(inputs.catalogText, 'pub const COURSE_COUNT : u8 = 10;', 'pub const COURSE_COUNT : u8 = 11;') }, 'the_basics_come_first') }) test('a broken claim in a spec fails its own test block', async () => { diff --git a/apps/website/specs/course/courses.t27 b/apps/website/specs/course/courses.t27 index c3e45d88e1..5bcd8cc900 100644 --- a/apps/website/specs/course/courses.t27 +++ b/apps/website/specs/course/courses.t27 @@ -28,10 +28,10 @@ pub const SCHEMA_VERSION : u8 = 1; ; nothing (#/verify-hardware had no route). pub const GENERATED : [2]str = ["src/lib/course.generated.ts", "src/lib/courseRoutes.generated.ts"]; -pub const COURSE_COUNT : u8 = 9; +pub const COURSE_COUNT : u8 = 10; -pub const COURSE_IDS : [9]str = ["t27-basics", "course", "ai-numbers", "goldenfloat", "verify-hardware", "clocks-and-cdc", "buses-and-peripherals", "ternary-computing", "arithmetic-and-dsp"]; -pub const COURSE_SPECS : [9]str = ["specs/course/t27-basics.t27", "specs/course/course.t27", "specs/course/ai-numbers.t27", "specs/course/goldenfloat.t27", "specs/course/verify-hardware.t27", "specs/course/clocks-and-cdc.t27", "specs/course/buses-and-peripherals.t27", "specs/course/ternary-computing.t27", "specs/course/arithmetic-and-dsp.t27"]; +pub const COURSE_IDS : [10]str = ["t27-basics", "course", "ai-numbers", "goldenfloat", "verify-hardware", "clocks-and-cdc", "buses-and-peripherals", "ternary-computing", "arithmetic-and-dsp", "neural-networks"]; +pub const COURSE_SPECS : [10]str = ["specs/course/t27-basics.t27", "specs/course/course.t27", "specs/course/ai-numbers.t27", "specs/course/goldenfloat.t27", "specs/course/verify-hardware.t27", "specs/course/clocks-and-cdc.t27", "specs/course/buses-and-peripherals.t27", "specs/course/ternary-computing.t27", "specs/course/arithmetic-and-dsp.t27", "specs/course/neural-networks.t27"]; pub const LESSONS_PER_COURSE : u8 = 27; pub const MODULES_PER_COURSE : u8 = 9; @@ -50,7 +50,7 @@ test every_course_is_three_cubed { } test the_basics_come_first { - assert COURSE_COUNT == 9; + assert COURSE_COUNT == 10; assert COURSE_IDS[0] == "t27-basics"; assert COURSE_SPECS[0] == "specs/course/t27-basics.t27"; assert COURSE_IDS[1] == "course"; @@ -65,7 +65,12 @@ test the_ternary_machine_follows_the_buses { assert COURSE_SPECS[7] == "specs/course/ternary-computing.t27"; } -test arithmetic_and_dsp_closes_the_catalog { +test arithmetic_and_dsp_follows_the_ternary_machine { assert COURSE_IDS[8] == "arithmetic-and-dsp"; assert COURSE_SPECS[8] == "specs/course/arithmetic-and-dsp.t27"; } + +test neural_networks_close_the_catalog { + assert COURSE_IDS[9] == "neural-networks"; + assert COURSE_SPECS[9] == "specs/course/neural-networks.t27"; +} diff --git a/apps/website/specs/course/neural-networks-ru.t27 b/apps/website/specs/course/neural-networks-ru.t27 new file mode 100644 index 0000000000..ce9746e94c --- /dev/null +++ b/apps/website/specs/course/neural-networks-ru.t27 @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/course/neural-networks-ru.t27 -- translation contract, Russian, for the course on neural networks +; Specs are English-only (LANG-EN, L3). This module carries no translated word: it +; says WHICH fields of specs/course/neural-networks.t27 the Russian bundle translates, WHERE +; the bundle lives, HOW it is keyed and what the page does when a field is missing. +; The Cyrillic text is in the bundle named by BUNDLE_PATH, never in a .t27 file. +; apps/website/scripts/course-from-spec.mjs refuses the build when the bundle misses +; a field (COVERAGE_REQUIRED), carries a key the course does not have +; (ORPHANS_ALLOWED), changes a number, or drops a {placeholder}. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module neural_networks_ru; + +pub const KIND : str = "i18n"; +pub const LOCALE : str = "ru"; +pub const SOURCE_LOCALE : str = "en"; +pub const SOURCE_SPEC : str = "specs/course/neural-networks.t27"; +pub const BUNDLE_REPO : str = "trinity"; +pub const BUNDLE_PATH : str = "apps/website/i18n/neural-networks.ru.json"; +pub const BUNDLE_FORMAT : str = "json"; +; A module entry is keyed by its MODULE_IDS value, a lesson entry by its LESSON_IDS +; value; the page strings sit under the key UI_KEY, keyed by the SAY_ name. +pub const MODULE_FIELDS : [2]str = ["TITLE", "LINE"]; +pub const LESSON_FIELDS : [4]str = ["TITLE", "GOAL", "TEXT", "TASK"]; +pub const UI_KEY : str = "ui"; +pub const FALLBACK : str = "en"; +; true: a module, lesson or page string with no Russian fails the build. +pub const COVERAGE_REQUIRED : bool = true; +; false: a bundle key the course does not have fails the build. +pub const ORPHANS_ALLOWED : bool = false; +pub const ENABLED : bool = true; + +test the_course_is_translated_whole { + assert COVERAGE_REQUIRED == true; + assert ORPHANS_ALLOWED == false; + assert LOCALE == "ru"; + assert FALLBACK == "en"; +} diff --git a/apps/website/specs/course/neural-networks.t27 b/apps/website/specs/course/neural-networks.t27 new file mode 100644 index 0000000000..7d365b8726 --- /dev/null +++ b/apps/website/specs/course/neural-networks.t27 @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/course/neural-networks.t27 -- the t27 course on neural networks, from one neuron to a transformer block +; Source of truth for apps/website/scripts/course-from-spec.mjs (gHashTag/trinity), which reads +; it the way it reads specs/course/course.t27: the constant schema, every test block below, every +; widget in specs/widgets/gallery.t27, every lesson spec compiled clean, the Russian bundle named +; by specs/course/neural-networks-ru.t27. It writes this course into src/lib/course.generated.ts +; (the page at #/neural-networks) and a byte-identical copy of this file at +; public/learn/neural-networks.t27. ASCII only (L3), English only (LANG-EN). + +; WHAT THE COURSE IS: course 10 of specs/course/courses.t27, 27 lessons in 9 modules of 3: one +; neuron, new bends, a layer, pictures, the error, downhill, learning, memory and attention, and +; the transformer and the reward. Every lesson opens one interactive widget and one spec. The +; agents of this project think with neural networks; this course opens their parts as the +; gHashTag/t27 specs/ml specs they are written in, each with numeric tests. Every widget runs the +; fn bodies of one of those specs compiled to WebAssembly (public/widgets//logic.js, held to +; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059. + +; WHAT THE COURSE DOES NOT DO: it says no number of its own. Every number in a lesson is one the +; lesson spec computes and its widget shows. Lesson 10 is average pooling, not a convolution: the +; sliding conv2d spec (gHashTag/t27#10612) was not merged when the course was made, and the +; lesson says so. Lesson 20 shows the four inputs of XOR, not a decision region over the plane. + +; WHY 27: 3 cubed lessons, the size of a TRI-27 word. Changing the shape changes the tests. +; phi^2 + 1/phi^2 = 3 | TRINITY + +module neural_networks; + +pub const KIND : str = "course"; +pub const ID : str = "neural-networks"; +pub const SCHEMA_VERSION : u8 = 1; +; The derived files the generator rewrites (relative to apps/website). +pub const GENERATED : [2]str = ["src/lib/course.generated.ts", "public/learn/neural-networks.t27"]; +pub const ROUTE : str = "neural-networks"; +; Share pages: learn/ for course 1, learn// for the next (specs/course/courses.t27). +pub const SHARE_PATH : str = "learn/neural-networks/"; +; The paid training every course page links to (specs/course/arithmetic-and-dsp.t27). +pub const COHORT_ROUTE : str = "fpga-training"; +pub const GALLERY : str = "specs/widgets/gallery.t27"; +pub const LOCALES : [2]str = ["en", "ru"]; +pub const RU_CONTRACT : str = "specs/course/neural-networks-ru.t27"; +; Lesson marks the reader sets are kept in this browser only, under this key, one key for +; every course. +pub const PROGRESS_KEY : str = "t27-course-done"; +pub const SENDS_NOTHING : bool = true; +; A lesson's widget is the page's main stage, so it is drawn taller than a +; gallery card (specs/widgets/gallery.t27 EMBED_* heights are for embeds in posts). +pub const TOOL_FRAME_HEIGHT : u16 = 760; +pub const PLAYER_FRAME_HEIGHT : u16 = 480; + +; --- Words on the page --------------------------------------------------------------------- +pub const TITLE : str = "Neural networks in t27: from one neuron to a transformer block"; +pub const DESCRIPTION : str = "Course 10, 27 lessons, a live widget and a t27 spec each: activations, softmax and embeddings, pooling and batch norm, losses, SGD, RMSProp and Adam, backpropagation and XOR, recurrent cells, attention, a transformer block and PPO. Every number is computed by a compiled spec."; +pub const SAY_KICKER : str = "Course"; +pub const SAY_LEAD : str = "The agents of this project think with neural networks, and here their parts are written as t27 specs with tests, specs the compiler checks. Every widget runs the fn bodies of a specs/ml spec compiled to WebAssembly: move a slider and the spec answers."; +pub const SAY_SHAPE : str = "9 modules of 3 lessons, 27 cells. A filled cell is a lesson you marked done."; +pub const SAY_START : str = "Start lesson 1"; +pub const SAY_CONTINUE : str = "Continue"; +pub const SAY_MODULE : str = "Module {0}"; +pub const SAY_LESSON : str = "Lesson {0} of {1}"; +pub const SAY_GOAL : str = "You will learn"; +pub const SAY_TRY : str = "Try it"; +pub const SAY_ALSO : str = "Also try"; +pub const SAY_ALSO_HINT : str = "Each one swaps the widget above."; +pub const SAY_BACK_TO_MAIN : str = "Back to this lesson's widget"; +pub const SAY_SPEC : str = "Open the lesson's spec in the player"; +pub const SAY_OPEN_PAGE : str = "Open the widget on its own page"; +pub const SAY_WIDGET_LANG : str = "Widgets keep their own English words: each one lives in its own t27 spec."; +pub const SAY_PREV : str = "Previous"; +pub const SAY_NEXT : str = "Next"; +pub const SAY_ALL : str = "All lessons"; +pub const SAY_MARK : str = "Mark as done"; +pub const SAY_MARKED : str = "Done"; +pub const SAY_PROGRESS : str = "{0} of {1} done"; +pub const SAY_PRIVATE : str = "Progress stays in this browser; nothing is sent."; +pub const SAY_SOURCE : str = "This course is itself a t27 spec: read it"; +pub const SAY_COHORT : str = "Looking for the paid FPGA training? It moved to its own page."; +pub const SAY_NOT_FOUND : str = "No lesson has this address."; +pub const SAY_OPEN_LESSON : str = "Open the interactive lesson"; +pub const SAY_OPEN_COURSE : str = "Open the interactive course"; +pub const SAY_SEO_TITLE : str = "{0}: neural networks course, lesson {1} of {2}"; +pub const SAY_SHARE : str = "Link to share, with a preview card"; +pub const SAY_NEXT_COURSE : str = "Next course"; +pub const SAY_PREV_COURSE : str = "Previous course"; + +; --- Modules ------------------------------------------------------------------------------- +pub const LESSONS_PER_MODULE : u8 = 3; +pub const MODULE_COUNT : u8 = 9; +pub const MODULE_IDS : [9]str = ["one-neuron", "new-bends", "a-layer", "pictures", "the-error", "downhill", "learning", "memory-and-attention", "transformer-and-reward"]; +pub const MODULE_TITLES : [9]str = [ + "One neuron", + "New bends", + "A layer", + "Pictures", + "The error", + "Downhill", + "Learning", + "Memory and attention", + "The transformer and the reward" +]; +pub const MODULE_LINES : [9]str = [ + "A neuron sums its inputs and bends the sum: ReLU, the sigmoid and tanh, and where each one stops passing a gradient back.", + "The smooth curves of current models: GELU with its dip, Swish with its knob, and ELU with a floor instead of a cliff.", + "What sits around the neurons: softmax turns scores into a choice, an embedding turns a word into numbers, dropout switches units off.", + "Reading a picture in patches: a window averaged over its patch, max pooling, and batch normalisation of features on different scales.", + "How wrong a guess is, as one number: mean squared error, cross-entropy for probabilities, and the Huber loss for outliers.", + "Walking down the loss: gradient descent with momentum, RMSProp that ignores the gradient's size, and Adam that combines them.", + "Where the gradients come from and what they achieve: backpropagation through a layer, a network that learns XOR, and LAMB for large batches.", + "Networks that read a sequence: a recurrent cell and its fading echo, the gates of an LSTM, and attention over every position at once.", + "The parts of a transformer and of an agent: positions as clocks, one encoder block, and PPO, which learns from reward without lurching." +]; + +; --- Lessons ------------------------------------------------------------------------------- +; LESSON_WIDGETS names the widget the lesson opens; every one is a gallery id, and no two +; lessons of any course open the same one. Each module's three widgets are offered in each +; other's LESSON_ALSO, next to related widgets of this course and of the ternary course. +; LESSON_SPECS is the spec under public/t27/files/ the lesson opens in the player, and the spec +; whose compiled fn bodies the widget runs. +pub const LESSON_COUNT : u8 = 27; +pub const LESSON_IDS : [27]str = [ + "relu", "the-sigmoid", "tanh-and-saturation", + "gelu", "swish-and-silu", "elu", + "softmax-and-temperature", "embeddings", "dropout", + "patches-of-a-picture", "max-pooling", "batch-normalisation", + "mean-squared-error", "cross-entropy", "the-huber-loss", + "gradient-descent", "rmsprop", "adam", + "backpropagation", "learning-xor", "lamb-and-large-batches", + "a-recurrent-cell", "lstm-gates", "attention", + "positional-encoding", "an-encoder-block", "ppo-and-the-reward" +]; +pub const LESSON_MODULES : [27]str = [ + "one-neuron", "one-neuron", "one-neuron", + "new-bends", "new-bends", "new-bends", + "a-layer", "a-layer", "a-layer", + "pictures", "pictures", "pictures", + "the-error", "the-error", "the-error", + "downhill", "downhill", "downhill", + "learning", "learning", "learning", + "memory-and-attention", "memory-and-attention", "memory-and-attention", + "transformer-and-reward", "transformer-and-reward", "transformer-and-reward" +]; +pub const LESSON_WIDGETS : [27]str = [ + "nn-relu", "nn-sigmoid", "nn-tanh", + "nn-gelu", "nn-silu", "nn-elu", + "nn-softmax", "nn-embedding", "nn-dropout", + "nn-conv", "nn-maxpool", "nn-batchnorm", + "nn-mse", "nn-bce", "nn-huber", + "nn-sgd", "nn-rmsprop", "nn-adam", + "nn-backprop", "nn-xor", "nn-lamb", + "nn-rnn", "nn-lstm", "nn-attention", + "nn-positions", "nn-encoder", "nn-ppo" +]; +pub const LESSON_ALSO : [27]str = [ + "nn-sigmoid,nn-tanh,tc-one-neuron", + "nn-relu,nn-tanh,nn-bce", + "nn-relu,nn-sigmoid", + "nn-silu,nn-elu,nn-encoder", + "nn-gelu,nn-elu,nn-relu", + "nn-relu,nn-silu,nn-gelu", + "nn-embedding,nn-dropout,nn-bce", + "nn-softmax,nn-dropout,nn-positions", + "nn-softmax,nn-embedding", + "nn-maxpool,nn-batchnorm,tc-detector", + "nn-conv,nn-batchnorm", + "nn-conv,nn-maxpool,nn-encoder", + "nn-bce,nn-huber", + "nn-mse,nn-huber,nn-sigmoid", + "nn-mse,nn-bce", + "nn-rmsprop,nn-adam,nn-mse", + "nn-sgd,nn-adam", + "nn-sgd,nn-rmsprop,nn-lamb", + "nn-xor,nn-lamb,tc-tiny-layer", + "nn-backprop,nn-lamb,tc-tiny-layer", + "nn-adam,nn-xor,nn-backprop", + "nn-lstm,nn-attention", + "nn-rnn,nn-attention,nn-sigmoid", + "nn-rnn,nn-lstm,nn-encoder", + "nn-attention,nn-encoder,nn-embedding", + "nn-attention,nn-positions,nn-batchnorm", + "nn-softmax,nn-adam,nn-encoder" +]; +pub const LESSON_SPECS : [27]str = [ + "specs/ml/activation/relu_activation.t27", + "specs/ml/activation/sigmoid_activation.t27", + "specs/ml/activation/tanh_activation.t27", + "specs/ml/activation/gelu_activation.t27", + "specs/ml/activation/silu_swish_activation.t27", + "specs/ml/activation/elu_activation.t27", + "specs/ml/activation/softmax.t27", + "specs/ml/layers/embedding_layer.t27", + "specs/ml/layers/dropout_layer.t27", + "specs/ml/layers/avgpool2d_layer.t27", + "specs/ml/layers/maxpool2d_layer.t27", + "specs/ml/layers/batchnorm_layer.t27", + "specs/ml/loss/mse_loss.t27", + "specs/ml/loss/binary_crossentropy_loss.t27", + "specs/ml/loss/huber_loss.t27", + "specs/ml/optimizer/sgd.t27", + "specs/ml/optimizer/rmsprop.t27", + "specs/ml/optimizer/adam.t27", + "specs/ml/layers/dense_layer.t27", + "specs/ml/pathway/mlp.t27", + "specs/ml/optimizer/lamb.t27", + "specs/ml/recurrent/rnn_cell.t27", + "specs/ml/recurrent/lstm_single.t27", + "specs/ml/recurrent/attention_mechanism.t27", + "specs/ml/transformer/positional_encoding.t27", + "specs/ml/transformer/encoder_block.t27", + "specs/ml/rl/ppo_clip_loss.t27" +]; +pub const LESSON_TITLES : [27]str = [ + "ReLU: keep the positive part", + "The sigmoid: a number into a probability", + "tanh and saturation", + "GELU: a dip below zero", + "Swish and SiLU", + "ELU: a floor, not a cliff", + "Softmax and temperature", + "Embeddings", + "Dropout", + "Patches of a picture", + "Max pooling", + "Batch normalisation", + "Mean squared error", + "Cross-entropy", + "The Huber loss", + "Gradient descent", + "RMSProp", + "Adam", + "Backpropagation", + "Learning XOR", + "LAMB and large batches", + "A recurrent cell", + "LSTM gates", + "Attention", + "Positional encoding", + "An encoder block", + "PPO and the reward" +]; +pub const LESSON_GOALS : [27]str = [ + "What ReLU does to a positive and to a negative input, and why a slope of 0 stops a unit from learning.", + "How the sigmoid maps any input to a probability, and why its slope limits deep networks.", + "Why tanh is centred on zero, and where its slope falls so low that a unit stops learning.", + "What GELU computes, why it dips below zero, and how close its tanh shortcut comes.", + "How x times sigmoid(beta x) gates itself, and how one parameter moves it from a smooth curve to ReLU.", + "How ELU keeps a soft negative side with a floor at -alpha, and why its slope never quite dies.", + "How softmax turns scores into probabilities that sum to one, and what the temperature does to them.", + "How a token becomes a row of numbers, and why learning changes only the rows that were read.", + "Why switching units off while training helps, and why the survivors must be scaled.", + "Why networks read a picture in patches, and what a 2 x 2 window averaged over each patch gives.", + "What max pooling keeps, where it remembers taking it from, and where the gradient goes.", + "How batch norm puts features on different scales on one scale, and what it uses at inference.", + "How MSE turns every miss into one number, why it chases large errors, and where its gradient points.", + "Why cross-entropy charges a confident wrong answer so much, and why that is what trains a classifier.", + "How the Huber loss treats a small error like squared error and a large one linearly, so outliers pull less.", + "How gradient descent walks down a loss, what momentum adds, and why too large a rate never settles.", + "How RMSProp divides each step by a running root mean square, so the step no longer depends on the gradient's size.", + "How Adam combines momentum with a running scale, and why its bias correction makes step 1 a fixed size.", + "How the gradient of each weight and each input of a layer follows from the gradient of its outputs.", + "Why one neuron cannot learn XOR, and how a hidden layer trained by backpropagation does.", + "How LAMB scales each layer's step by its own weight norm, so one learning rate suits layers of every size.", + "How a recurrent cell carries a state from step to step, and why that memory fades.", + "How the forget, input and output gates of an LSTM decide what the cell keeps, writes and shows.", + "How attention scores every query against every key, what a softmax over each row gives, and what the causal mask removes.", + "How sines and cosines at falling frequencies give every position its own vector, and why a shift is a turn.", + "What one transformer encoder block does to its input, and what moving the norms in front changes.", + "How PPO turns a reward into a policy update, and how its clip keeps one update from going too far." +]; +pub const LESSON_TEXTS : [27]str = [ + "A neuron adds up its weighted inputs and passes the sum through an activation. ReLU is the plainest one, max(0, x): a positive sum goes through unchanged and a negative one becomes 0. Its slope is 1 or 0, and a slope of 0 is a unit that has stopped learning, because no gradient flows back through it. A leaky slope fixes that: with a slope of 0.1, x = -2 gives -0.2 and passes back a gradient of 0.1. The spec relu_activation.t27 computes both curves the widget draws.", + "The sigmoid 1 / (1 + e^-x) squeezes the whole number line into 0 to 1, which is why it reads as a probability: 2 becomes 0.8808 and -4 becomes 0.018. Its slope is s (1 - s), computed from the output s itself, and it is largest at 0, where it is 0.25; at x = 8 it is 0.000335. A gradient that passes back through a stack of sigmoids is multiplied by at most 0.25 at each one, which is why deep sigmoid networks trained slowly. The spec sigmoid_activation.t27 computes the curve and the slope.", + "tanh is a sigmoid stretched to -1..1 and centred on 0, so a layer of tanh units passes on values that average near zero, and its slope reaches 1 at the centre. It still saturates: at 2.5 the output is 0.9866 and the slope only 0.0266. The red band marks every input where the slope is under 0.1, beyond about 1.8 on either side, and a unit whose inputs live there barely learns. The spec tanh_activation.t27 computes the curve, the slope and its own batch, tanh of 0, 1 and 2: 0, 0.762 and 0.964.", + "GELU weighs x by the chance that a standard normal draw is below it: GELU(x) = x Phi(x). A large positive input passes, a large negative one vanishes, and in between the curve dips to about -0.17 near x = -0.75 before it rises. BERT and GPT use it in their feed-forward layers. The exact form needs erf, which the spec computes with the Abramowitz-Stegun fit, good to 1.5e-7, and it also computes the tanh shortcut: at -0.75 they give -0.16997 and -0.17004. The spec gelu_activation.t27 computes both curves and their slopes.", + "Swish is x times sigmoid(beta x), a unit that gates itself. At beta 1 it is called SiLU, and its lowest point is -0.2785 near x = -1.28. Raise beta and the gate sharpens: at beta 8 the curve is ReLU with rounded corners; at beta 0.5 it is a gentle slope through zero. One parameter moves the unit between a smooth curve and a switch, and a network can learn it. The spec silu_swish_activation.t27 computes the curve and its slope for any beta, and its own batch at -2, 0 and 2: -0.238, 0 and 1.762.", + "ELU keeps the positive side of ReLU and replaces the cliff on the negative side with alpha (e^x - 1), a curve that flattens toward -alpha. With alpha 1, x = -3 gives -0.9502, already near the floor of -1, and the slope there is 0.0498: small, but not 0, so the unit can still move. Because the negative outputs are not thrown away, a layer's outputs average closer to 0. The spec elu_activation.t27 computes the curve, the slope and the floor, and its own batch at -1, 0 and 2: -0.632, 0 and 2.", + "A classifier ends with one score per class, and softmax turns the scores into probabilities: exp of each score over the sum of all of them. Scores 1, 2 and 3 become 0.090, 0.245 and 0.665. Dividing the scores by a temperature first changes how sure it is: at 0.5 the top score takes 0.867, at 5 the three are 0.27, 0.33 and 0.40. A language model picks its next token from exactly this, and the temperature setting of a chat model is this T. The spec softmax.t27 subtracts the largest score first, so exp never overflows.", + "A network cannot multiply a word, so each token is an index into a table with one row of numbers per token, and looking a token up copies its row. In the spec the table has 4 tokens of width 2 and row v holds (10 v, 10 v + 1), so token 2 reads (20, 21). Learning sends the gradient back only to the rows that were read, and a token read twice collects both: gradient rows (1, 2) and (3, 4) on token 2 add up to (4, 6). The spec embedding_layer.t27 computes the lookup and the gradient.", + "While training, dropout switches off a share p of the units at random, so the rest cannot lean on any one of them. The units that survive must then be scaled, or the next layer would see the signal at another size in training than at inference. Inverted dropout scales them by 1 / (1 - p) while training: with p = 0.5, input 1, 2, 3, 4 becomes 2, 0, 6, 0, and inference is a plain pass. Classic dropout keeps 1, 0, 3, 0 and scales by 0.5 at inference instead. The spec dropout_layer.t27 uses a fixed mask, keep, drop, keep, drop, so the numbers are the same every time.", + "A picture is a grid of numbers, and networks read it in small patches so that the same detector works anywhere in it. Here a 2 x 2 window steps by 2 over a 4 x 4 image whose cell i holds i, and each output is the average of its patch: 2.5, 4.5, 10.5 and 12.5. In the backward pass each output's gradient is split equally over its 4 cells. This is average pooling: a convolution would weight the 4 cells with a learned kernel, and its spec, t27#10612, is not merged yet. The spec avgpool2d_layer.t27 computes both passes.", + "Max pooling keeps the largest value of each window and drops the rest, so the network cares less about exactly where a feature sits. On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2, taken from cells 5, 6, 13 and 11. Overlapping 3 x 3 windows with stride 1 keep 8, 8, 9 and 9. In the backward pass each window's whole gradient goes to its maximum: gradients 1, 2, 3 and 4 land on cells 5, 6, 13 and 11, and every other cell gets 0. The spec maxpool2d_layer.t27 computes the outputs, their positions and the gradient.", + "Features on different scales pull a network around: in the spec's batch one feature is ten times another. Batch normalisation subtracts each feature's batch mean and divides by its spread, so the features 1, 2, 3, 4 and 10, 20, 30, 40 both come out as -1.34, -0.45, 0.45 and 1.34, and -1, -1, 1, 1 comes out as -1 and 1. A learned gamma and beta then scale and shift it back where that helps. At inference the layer uses running averages instead of the batch: with mean 0, variance 1, gamma 1 and beta 0.25, the inputs 1, 2 and 3 give 1.25, 2.25 and 3.25. The spec batchnorm_layer.t27 computes both.", + "A loss turns all the misses of a model into one number to push down. Mean squared error averages the squared misses: predictions 1.5, 2 and 2 against targets 1, 2 and 3 cost (0.25 + 0 + 1) / 3 = 0.4167. Squaring makes a miss of 2 cost 4 times a miss of 1, so MSE chases large errors. Its gradient for each prediction is 2 (p - t) / n, here 0.333, 0 and -0.667: each prediction is pushed back toward its target. As a function of one prediction the loss is a parabola, a bowl with one bottom. The spec mse_loss.t27 computes the loss and the gradient.", + "A classifier outputs a probability, and cross-entropy charges -log of the probability it gave to the true answer. Predictions 0.8, 0.3 and 0.9 against answers 1, 0 and 1 cost 0.2284 on average. Being sure and right is nearly free: 0.99, 0.01 and 0.99 cost 0.0101. Being sure and wrong is expensive: 0.01, 0.99 and 0.01 cost 4.6052, and toward 0 the cost grows without bound, which is why the spec clips p to [1e-7, 1 - 1e-7]. Its gradient is largest exactly where the model is sure and wrong. The spec binary_crossentropy_loss.t27 computes the loss and the gradient, from probabilities or from logits.", + "Squared error lets one outlier dominate: an error of 3 costs 4.5 as half its square, as much as 36 errors of 0.5. Huber is half the square while |e| is within delta and then grows only linearly, delta |e| - delta^2 / 2, so with delta 1 that error costs 2.5. The two pieces meet with the same value and slope, and the gradient never grows past delta: a far-off point pulls on the model with a bounded force. For the spec's pair of errors 0.5 and 3 the mean is 1.3125, against 2.3125 for half the square. The spec huber_loss.t27 computes both.", + "Training is walking downhill on the loss. Gradient descent moves a weight by -lr times its gradient each step; in the spec the loss is (x - 3)^2 from x = 0, and lr 0.1 reaches 2.99996 in 50 steps. Momentum adds a share of the last move, which speeds up a long slope and overshoots a sharp bottom: at 0.9 the weight shoots past 3 to about 5.13 and rings down to 3.09 after 50 steps. Nesterov takes the gradient one step ahead and swings less, to about 4.25. Too large a rate never settles: at lr 1 the weight bounces between 0 and 6 for good. The spec sgd.t27 computes every step.", + "The right step size depends on the size of the gradient, and different weights see gradients a million times apart. RMSProp keeps a running mean of the squared gradient, the cache, and divides each step by its root, so the step has no units: with a constant gradient of 0.001, 0.5 or 1000 the weight moves by exactly the same 0.0316 on step 1 and walks the same path, reaching -0.0914 after 100 steps at lr 0.01. The decay sets how slowly the cache fills: at 0.99 the same 100 steps end at -1.0261. The spec rmsprop.t27 computes the weight and the cache.", + "Adam combines the two ideas: m, a running mean of the gradient, as in momentum, and v, a running mean of its square, as in RMSProp; the step is lr m / sqrt(v). Both start at 0 and are too small early on, so Adam divides them by 1 - beta^t, and on step 1 that makes the move exactly lr times the sign of the gradient: gradients 2, -40 and 0.5 all move their weights by 0.001. On the spec's bowl (x - 3)^2 at lr 0.1, Adam rises from 0, overshoots to about 3.18 and settles at 3.00005 by step 200. The spec adam.t27 computes every step.", + "To learn, every weight needs to know how the loss changes when it moves. Backpropagation answers one layer at a time: given g, how much the loss wants each output to move, the weight from input i to output o gets g_o x_i, and input i gets the sum over o of W[o][i] g_o, which it hands on to the layer below. With inputs (1, 2, 3) and g = (1, 0.5) the weight gradients are 1, 2, 3 and 0.5, 1, 1.5, and the input gradients 0.5, 2 and 3.5. The layer is linear, so moving x0 by 1 moves the loss g . y from 15.25 to 15.75, by its gradient 0.5. The spec dense_layer.t27 computes all three.", + "XOR is 1 when exactly one of two inputs is 1. No straight line separates the cases that give 1 from those that give 0, so a single neuron cannot learn it. A hidden layer bends the space: the spec trains a 2-8-1 network of ReLUs by backpropagation, lr 0.05, from fixed initial weights. Its loss falls from 0.8896 in epoch 1 to 1.8e-13 after 2000 epochs, and its four answers come out within 4e-7 of 0, 1, 1 and 0. The widget runs that training in your browser, from scratch for every point of the curve. The spec mlp.t27 holds the network and the test that it learns.", + "Training with very large batches needs a large learning rate, and one rate can be too large for a small layer and too small for a big one. LAMB takes an Adam-style update for each layer and rescales it by the trust ratio, the layer's weight norm, capped at 10, over the update's norm, so every layer moves by the same fraction of itself. In the spec, the weights (1, 2) times a scale take a step whose norm is 0.001 times theirs: 0.00447 at scale 2, and once the weight norm passes 10, near scale 4.47, the step stays at 0.01. The spec lamb.t27 computes the update for one layer and for two at once.", + "A sentence comes one word at a time, and a recurrent cell carries a state h from one step to the next: h' = tanh(W_x x + W_h h + b). In the spec's tiny cell W_x is 1 and W_h 0.5, so a single pulse gives 0.7616, 0.3634 and 0.1797: the memory of it roughly halves each step. A second pulse at step 3 lifts h to 0.7968, a little above where the single pulse began, because the old memory is still there. After 8 steps only 0.0466 is left. That fading is why plain cells forget long contexts. The spec rnn_cell.t27 computes each step.", + "An LSTM cell keeps a separate memory c and three gates, each a sigmoid between 0 and 1: forget scales the old memory, input lets in new content g, and output decides how much of the memory to show. c' = f c + i g and h' = o tanh(c'). In the spec's fixture every weight is 0, so each gate is the sigmoid of its bias: with the forget gate at 0.9975 and the input gate at 0.0025, a memory of 1 comes out as 0.9975, and the output is 0.7587. Because c passes through with only a multiply by f, its gradient survives many steps too. The spec lstm_single.t27 computes the cell.", + "Attention lets each position decide which other positions to read. Every query is scored against every key, q . k / sqrt(d), and a softmax turns each row of scores into weights that sum to 1; the output is the values averaged by those weights. Two heads do it on the two halves of the vector. With a causal mask a position cannot read the future: in head 0, position 0 reads only itself, position 1 splits 0.452 and 0.548, and position 2 spreads 0.230, 0.321 and 0.449. Without the mask every row spreads over all three keys, from 0.21 to 0.47. The spec attention_mechanism.t27 computes every weight on its own fixture.", + "Attention treats its input as a set, so the order of the words has to be added to them. The sinusoidal encoding gives each position d numbers: the sin and cos of the position times a frequency that falls by 10000^(2/d) from pair to pair. With d = 8 the four pairs turn by 1, 0.1, 0.01 and 0.001 radians per position, like the hands of four clocks: position 5 reads -0.959, 0.284 in its fast pair and 0.005, 1.000 in its slow one. Each pair has length 1, and a shift by k positions turns every pair by its own fixed angle. The spec positional_encoding.t27 computes every value.", + "A transformer layer is two sublayers, each wrapped in a residual add and a layer norm: self-attention mixes the positions, then a feed-forward net of width 8 works on each position alone. In the post-norm order of the original paper the block ends with a norm, so every output row has mean 0 and variance 1.000. Pre-norm puts the norms in front of each sublayer and ends on a residual add, so its rows come out at variances 2.73, 3.33 and 0.96; deep stacks train more easily that way, with one norm added at the very top. The spec encoder_block.t27 runs one block on 3 positions, d_model 4 and 2 heads.", + "An agent learns from reward by making good actions more likely. PPO measures a change of policy by the ratio r of the new probability of an action to the old one and multiplies it by the advantage A, how much better the action did than expected. Then it clips: once r has moved more than eps the way A rewards, the objective goes flat. At r = 1.5, A = 1 and eps 0.2 the raw r A is 1.5, but PPO counts 1.2, so one batch cannot push the policy far. On the spec's batch, ratios 1, 1.1 and 0.9 with advantages 2, 1.5 and 3, the policy loss is -2.1167. The spec ppo_clip_loss.t27 computes it." +]; +pub const LESSON_TASKS : [27]str = [ + "Put x at -2 and read the slope with and without the leak; then find the slope at x = 1.5.", + "Find the input where the probability is 0.5; then drag to 6 and read how little slope is left.", + "Drag x until the band starts and read the slope there; then compare the slope at 0 and at 2.5.", + "Find the lowest point of the curve by its slope; then compare the exact and the tanh form at -3.", + "Hold x at -1.28 and raise beta from 1 to 8; then find the beta at which the dip is gone at this scale.", + "Set alpha to 0.5 and read the floor; then find how far left x must go before the slope is under 0.01.", + "Cool the temperature to 0.1 and read the three probabilities; then make a tie and heat it.", + "Read token 2 twice and then tokens 1 and 3; count the rows whose gradient is not 0 each time.", + "Compare the outputs of the four modes; then read the gradient of a dropped unit in training.", + "Tap each patch and check its average by eye; then switch to the gradient and read what each cell of window 4 receives.", + "Switch to 3 x 3 windows and find the cell two outputs share; then turn on the gradient for 2 x 2 windows.", + "Compare the two normalised columns; then set the running mean 2 and variance 4 and read the inference outputs.", + "Move prediction 2 onto its target and read the loss; then drag along the bowl and find its bottom.", + "Drag prediction 0 toward 0.01 and watch the curve; then read the gradient bars at 0.5, 0.5 and 0.5.", + "Set delta to 0.5 and drag the error to 3; then find where the two curves part.", + "Find the largest learning rate that still settles without momentum; then add momentum 0.9 and count the swings.", + "Switch between the three gradients and check that the lines do not move; then raise the decay to 0.99.", + "Give the three gradients very different sizes and read the weights after step 1; then find where the path tops out.", + "Set g = (1, 0) and read which edges go dark; then set g = (-2, 1) and check the input gradients by hand.", + "Drag the epochs back to 100 and read the four answers; then find the epoch where the curve stops falling.", + "Read the step at scales 1 and 2 and compare; then drag past the bend and explain why the line goes flat.", + "Load one pulse and read how many steps it takes to fall under 0.1; then make the input alternate.", + "Load Remember and then Forget and compare the new memory; then write with the input gate open.", + "Turn the mask off and on and read row 0; then compare the two heads on row 2.", + "Step from position 0 to 1 and watch which clock moves; then jump to 37 and find the pair that still points up.", + "Switch between post-norm and pre-norm and read the row variances; then find the position head 1 reads most.", + "Make the advantage negative and find where the curve goes flat now; then widen eps to 0.5." +]; + +; --- Claims -------------------------------------------------------------------------------- +test the_course_is_three_cubed { + assert LESSONS_PER_MODULE == 3; + assert MODULE_COUNT == 9; + assert LESSON_COUNT == 27; + assert MODULE_COUNT * LESSONS_PER_MODULE == LESSON_COUNT; + assert LESSON_COUNT == 3 * 3 * 3; +} + +test it_starts_at_one_neuron_and_ends_with_a_reward { + assert MODULE_IDS[0] == "one-neuron"; + assert LESSON_WIDGETS[0] == "nn-relu"; + assert LESSON_SPECS[0] == "specs/ml/activation/relu_activation.t27"; + assert MODULE_IDS[8] == "transformer-and-reward"; + assert LESSON_WIDGETS[26] == "nn-ppo"; + assert LESSON_SPECS[26] == "specs/ml/rl/ppo_clip_loss.t27"; +} + +test activations_come_before_layers { + assert MODULE_IDS[1] == "new-bends"; + assert LESSON_WIDGETS[3] == "nn-gelu"; + assert MODULE_IDS[2] == "a-layer"; + assert LESSON_SPECS[6] == "specs/ml/activation/softmax.t27"; +} + +test the_picture_lesson_is_pooling_until_conv2d_slides { + assert MODULE_IDS[3] == "pictures"; + assert LESSON_WIDGETS[9] == "nn-conv"; + assert LESSON_SPECS[9] == "specs/ml/layers/avgpool2d_layer.t27"; + assert LESSON_WIDGETS[10] == "nn-maxpool"; +} + +test losses_then_optimizers_then_learning { + assert MODULE_IDS[4] == "the-error"; + assert MODULE_IDS[5] == "downhill"; + assert LESSON_WIDGETS[17] == "nn-adam"; + assert MODULE_IDS[6] == "learning"; + assert LESSON_WIDGETS[19] == "nn-xor"; + assert LESSON_SPECS[19] == "specs/ml/pathway/mlp.t27"; +} + +test memory_then_attention_then_the_transformer { + assert MODULE_IDS[7] == "memory-and-attention"; + assert LESSON_WIDGETS[23] == "nn-attention"; + assert LESSON_WIDGETS[25] == "nn-encoder"; + assert LESSON_SPECS[25] == "specs/ml/transformer/encoder_block.t27"; +} + +test the_course_sends_nothing { + assert SENDS_NOTHING == true; + assert LOCALES[0] == "en"; + assert LOCALES[1] == "ru"; +} diff --git a/apps/website/src/components/Navigation.tsx b/apps/website/src/components/Navigation.tsx index 6ebbdb3bd7..e69a7da76b 100644 --- a/apps/website/src/components/Navigation.tsx +++ b/apps/website/src/components/Navigation.tsx @@ -54,6 +54,7 @@ const PAGES: PageLink[] = [ { href: '#/buses-and-peripherals', en: 'Course: buses and peripherals', ru: 'Курс: шины и периферия', note: 'UART, SPI, APB, AXI4, Ethernet, 27 lessons', noteRu: 'UART, SPI, APB, AXI4, Ethernet, 27 уроков' }, { href: '#/ternary-computing', en: 'Course: the ternary machine', ru: 'Курс: троичная машина', note: 'Trits, logic, adders, a machine, neurons; a live widget per lesson, 27 lessons', noteRu: 'Триты, логика, сумматоры, машина, нейроны; живой виджет в каждом уроке, 27 уроков' }, { href: '#/arithmetic-and-dsp', en: 'Course: arithmetic and DSP', ru: 'Курс: арифметика и DSP', note: 'Adders, multipliers, fixed point, CORDIC, FIR, CIC, FFT, 27 lessons', noteRu: 'Сумматоры, умножители, фиксированная точка, CORDIC, FIR, CIC, БПФ, 27 уроков' }, + { href: '#/neural-networks', en: 'Course: neural networks', ru: 'Курс: нейросети', note: 'Activations, losses, Adam, backprop, XOR, attention, a transformer block, 27 lessons', noteRu: 'Активации, потери, Adam, обратное распространение, XOR, внимание, блок трансформера, 27 уроков' }, { href: '#/foundry', en: 'Golden Foundry', ru: 'Золотая Литейная', note: 'A club for people who build on silicon', noteRu: 'Клуб разработчиков на кремнии', color: '#C9A24B' }, { href: '#/about', en: 'About', ru: 'Об авторе', note: 'Background, papers, contact', noteRu: 'Биография, статьи, контакты' }, { href: '#/resources', en: 'Resources', ru: 'Материалы', note: 'Papers and datasets, each with a DOI', noteRu: 'Статьи и датасеты, у каждого DOI' }, diff --git a/apps/website/src/lib/course.generated.ts b/apps/website/src/lib/course.generated.ts index 3c3fb75ca8..64a355dea6 100644 --- a/apps/website/src/lib/course.generated.ts +++ b/apps/website/src/lib/course.generated.ts @@ -1,5 +1,5 @@ -// GENERATED by scripts/course-from-spec.mjs from specs/course/courses.t27, specs/course/t27-basics.t27, specs/course/course.t27, specs/course/ai-numbers.t27, specs/course/goldenfloat.t27, specs/course/verify-hardware.t27, specs/course/clocks-and-cdc.t27, specs/course/buses-and-peripherals.t27, specs/course/ternary-computing.t27, specs/course/arithmetic-and-dsp.t27 and their Russian bundles -// spec sha256 t27-basics 4827f6b9f5d95ae98e1d49f037966d2cc826e07c691044f2f5fa1ee9c98ae474, course 8429472829c5d9a0782b2d2b21ff26879a429c5470f4abb5088f1e1a7fa674be, ai-numbers 7f736e357ef13446dfa8f978482cc28c7710caac3f7396769a8fc01b91e20802, goldenfloat d6b6019b8e6bf77a41991b32a3a3d1b5eb78ca4b7078e2bf5f5436df3dd7c59c, verify-hardware 7ca437575eaa8f8646f42c82b75862f091fb509708de152c4e18ed76ee39d4cf, clocks-and-cdc 7d491967f9326fcde194ab19a9bfa7f0ed960ba94d7ca3d82df0747e269c5acc, buses-and-peripherals 4dfdbd8c909d7ad8f1ac2d4f7025c77f0619ade92b181212ea9b589262695acc, ternary-computing e0a14010163f00208d5b54c800e6ce3f05e6b8581de94c0323097b00b1854437, arithmetic-and-dsp c2b6bfd642e88caadaff9da965ac49172b389427b574b27d4c64145851bc206d +// GENERATED by scripts/course-from-spec.mjs from specs/course/courses.t27, specs/course/t27-basics.t27, specs/course/course.t27, specs/course/ai-numbers.t27, specs/course/goldenfloat.t27, specs/course/verify-hardware.t27, specs/course/clocks-and-cdc.t27, specs/course/buses-and-peripherals.t27, specs/course/ternary-computing.t27, specs/course/arithmetic-and-dsp.t27, specs/course/neural-networks.t27 and their Russian bundles +// spec sha256 t27-basics 4827f6b9f5d95ae98e1d49f037966d2cc826e07c691044f2f5fa1ee9c98ae474, course 8429472829c5d9a0782b2d2b21ff26879a429c5470f4abb5088f1e1a7fa674be, ai-numbers 7f736e357ef13446dfa8f978482cc28c7710caac3f7396769a8fc01b91e20802, goldenfloat d6b6019b8e6bf77a41991b32a3a3d1b5eb78ca4b7078e2bf5f5436df3dd7c59c, verify-hardware 7ca437575eaa8f8646f42c82b75862f091fb509708de152c4e18ed76ee39d4cf, clocks-and-cdc 7d491967f9326fcde194ab19a9bfa7f0ed960ba94d7ca3d82df0747e269c5acc, buses-and-peripherals 4dfdbd8c909d7ad8f1ac2d4f7025c77f0619ade92b181212ea9b589262695acc, ternary-computing e0a14010163f00208d5b54c800e6ce3f05e6b8581de94c0323097b00b1854437, arithmetic-and-dsp c2b6bfd642e88caadaff9da965ac49172b389427b574b27d4c64145851bc206d, neural-networks f87c70cb9d017c9a58161f94f304eb8e0cbe8f3c942747e2a17ef51a1075f161 // Do not edit: change the .t27 source (or a Russian bundle) and regenerate. export const COURSES = [ @@ -11865,6 +11865,1761 @@ export const COURSES = [ "ru": "Троичная машина: от трита до работающей программы" } }, + "next": { + "id": "neural-networks", + "route": "neural-networks", + "share": "learn/neural-networks/", + "first": "relu", + "last": "ppo-and-the-reward", + "title": { + "en": "Neural networks in t27: from one neuron to a transformer block", + "ru": "Нейросети на t27: от одного нейрона до блока трансформера" + } + } + }, + { + "id": "neural-networks", + "source": { + "spec": "specs/course/neural-networks.t27", + "publicSpec": "public/learn/neural-networks.t27", + "ruContract": "specs/course/neural-networks-ru.t27", + "ruBundle": "apps/website/i18n/neural-networks.ru.json", + "sha256": "f87c70cb9d017c9a58161f94f304eb8e0cbe8f3c942747e2a17ef51a1075f161", + "schemaVersion": 1, + "gallery": "specs/widgets/gallery.t27" + }, + "route": "neural-networks", + "share": "learn/neural-networks/", + "cohortRoute": "fpga-training", + "progressKey": "t27-course-done", + "sendsNothing": true, + "locales": [ + "en", + "ru" + ], + "say": { + "en": { + "TITLE": "Neural networks in t27: from one neuron to a transformer block", + "DESCRIPTION": "Course 10, 27 lessons, a live widget and a t27 spec each: activations, softmax and embeddings, pooling and batch norm, losses, SGD, RMSProp and Adam, backpropagation and XOR, recurrent cells, attention, a transformer block and PPO. Every number is computed by a compiled spec.", + "ALL": "All lessons", + "ALSO": "Also try", + "ALSO_HINT": "Each one swaps the widget above.", + "BACK_TO_MAIN": "Back to this lesson's widget", + "COHORT": "Looking for the paid FPGA training? It moved to its own page.", + "CONTINUE": "Continue", + "GOAL": "You will learn", + "KICKER": "Course", + "LEAD": "The agents of this project think with neural networks, and here their parts are written as t27 specs with tests, specs the compiler checks. Every widget runs the fn bodies of a specs/ml spec compiled to WebAssembly: move a slider and the spec answers.", + "LESSON": "Lesson {0} of {1}", + "MARK": "Mark as done", + "MARKED": "Done", + "MODULE": "Module {0}", + "NEXT": "Next", + "NEXT_COURSE": "Next course", + "NOT_FOUND": "No lesson has this address.", + "OPEN_COURSE": "Open the interactive course", + "OPEN_LESSON": "Open the interactive lesson", + "OPEN_PAGE": "Open the widget on its own page", + "PREV": "Previous", + "PREV_COURSE": "Previous course", + "PRIVATE": "Progress stays in this browser; nothing is sent.", + "PROGRESS": "{0} of {1} done", + "SEO_TITLE": "{0}: neural networks course, lesson {1} of {2}", + "SHAPE": "9 modules of 3 lessons, 27 cells. A filled cell is a lesson you marked done.", + "SHARE": "Link to share, with a preview card", + "SOURCE": "This course is itself a t27 spec: read it", + "SPEC": "Open the lesson's spec in the player", + "START": "Start lesson 1", + "TRY": "Try it", + "WIDGET_LANG": "Widgets keep their own English words: each one lives in its own t27 spec." + }, + "ru": { + "TITLE": "Нейросети на t27: от одного нейрона до блока трансформера", + "DESCRIPTION": "Курс 10, 27 уроков, в каждом живой виджет и спека t27: функции активации, softmax и эмбеддинги, пулинг и пакетная нормализация, функции потерь, SGD, RMSProp и Adam, обратное распространение и XOR, рекуррентные ячейки, внимание, блок трансформера и PPO. Каждое число вычисляет скомпилированная спека.", + "ALL": "Все уроки", + "ALSO": "Также откройте", + "ALSO_HINT": "Каждая кнопка меняет виджет сверху.", + "BACK_TO_MAIN": "Вернуться к виджету урока", + "COHORT": "Ищете платное обучение по FPGA? Оно переехало на отдельную страницу.", + "CONTINUE": "Продолжить", + "GOAL": "Вы узнаете", + "KICKER": "Курс", + "LEAD": "Агенты этого проекта думают нейросетями, а здесь их части записаны спеками t27 с тестами, которые проверяет компилятор. Каждый виджет исполняет тела fn спеки из specs/ml, скомпилированные в WebAssembly: двигаете ползунок — отвечает спека.", + "LESSON": "Урок {0} из {1}", + "MARK": "Отметить пройденным", + "MARKED": "Пройдено", + "MODULE": "Модуль {0}", + "NEXT": "Далее", + "NEXT_COURSE": "Следующий курс", + "NOT_FOUND": "У урока нет такого адреса.", + "OPEN_COURSE": "Открыть интерактивный курс", + "OPEN_LESSON": "Открыть интерактивный урок", + "OPEN_PAGE": "Открыть виджет на отдельной странице", + "PREV": "Назад", + "PREV_COURSE": "Предыдущий курс", + "PRIVATE": "Прогресс хранится только в этом браузере; ничего не отправляется.", + "PROGRESS": "{0} из {1} пройдено", + "SEO_TITLE": "{0}: курс о нейросетях, урок {1} из {2}", + "SHAPE": "9 модулей по 3 урока, 27 клеток. Заполненная клетка — урок, отмеченный пройденным.", + "SHARE": "Ссылка для шаринга, с карточкой предпросмотра", + "SOURCE": "Этот курс сам является спекой t27: прочитайте её", + "SPEC": "Открыть спеку урока в плеере", + "START": "Начать урок 1", + "TRY": "Попробовать", + "WIDGET_LANG": "Виджеты хранят свои английские слова: у каждого своя спека t27." + } + }, + "modules": [ + { + "id": "one-neuron", + "n": 1, + "lessons": [ + "relu", + "the-sigmoid", + "tanh-and-saturation" + ], + "en": { + "title": "One neuron", + "line": "A neuron sums its inputs and bends the sum: ReLU, the sigmoid and tanh, and where each one stops passing a gradient back." + }, + "ru": { + "title": "Один нейрон", + "line": "Нейрон складывает входы и изгибает сумму: ReLU, сигмоида и tanh, и где каждая перестаёт пропускать градиент назад." + } + }, + { + "id": "new-bends", + "n": 2, + "lessons": [ + "gelu", + "swish-and-silu", + "elu" + ], + "en": { + "title": "New bends", + "line": "The smooth curves of current models: GELU with its dip, Swish with its knob, and ELU with a floor instead of a cliff." + }, + "ru": { + "title": "Новые изгибы", + "line": "Гладкие кривые нынешних моделей: GELU с провалом, Swish с ручкой и ELU с полом вместо обрыва." + } + }, + { + "id": "a-layer", + "n": 3, + "lessons": [ + "softmax-and-temperature", + "embeddings", + "dropout" + ], + "en": { + "title": "A layer", + "line": "What sits around the neurons: softmax turns scores into a choice, an embedding turns a word into numbers, dropout switches units off." + }, + "ru": { + "title": "Слой", + "line": "Что окружает нейроны: softmax превращает оценки в выбор, эмбеддинг превращает слово в числа, dropout выключает нейроны." + } + }, + { + "id": "pictures", + "n": 4, + "lessons": [ + "patches-of-a-picture", + "max-pooling", + "batch-normalisation" + ], + "en": { + "title": "Pictures", + "line": "Reading a picture in patches: a window averaged over its patch, max pooling, and batch normalisation of features on different scales." + }, + "ru": { + "title": "Картинки", + "line": "Чтение картинки по участкам: окно, усреднённое по участку, max pooling и пакетная нормализация признаков разного масштаба." + } + }, + { + "id": "the-error", + "n": 5, + "lessons": [ + "mean-squared-error", + "cross-entropy", + "the-huber-loss" + ], + "en": { + "title": "The error", + "line": "How wrong a guess is, as one number: mean squared error, cross-entropy for probabilities, and the Huber loss for outliers." + }, + "ru": { + "title": "Ошибка", + "line": "Насколько неверна догадка, одним числом: среднеквадратичная ошибка, перекрёстная энтропия для вероятностей и функция Хьюбера для выбросов." + } + }, + { + "id": "downhill", + "n": 6, + "lessons": [ + "gradient-descent", + "rmsprop", + "adam" + ], + "en": { + "title": "Downhill", + "line": "Walking down the loss: gradient descent with momentum, RMSProp that ignores the gradient's size, and Adam that combines them." + }, + "ru": { + "title": "Под гору", + "line": "Спуск по функции потерь: градиентный спуск с моментом, RMSProp без оглядки на величину градиента и Adam, который соединяет оба." + } + }, + { + "id": "learning", + "n": 7, + "lessons": [ + "backpropagation", + "learning-xor", + "lamb-and-large-batches" + ], + "en": { + "title": "Learning", + "line": "Where the gradients come from and what they achieve: backpropagation through a layer, a network that learns XOR, and LAMB for large batches." + }, + "ru": { + "title": "Обучение", + "line": "Откуда берутся градиенты и чего они добиваются: обратное распространение через слой, сеть, которая учит XOR, и LAMB для больших пакетов." + } + }, + { + "id": "memory-and-attention", + "n": 8, + "lessons": [ + "a-recurrent-cell", + "lstm-gates", + "attention" + ], + "en": { + "title": "Memory and attention", + "line": "Networks that read a sequence: a recurrent cell and its fading echo, the gates of an LSTM, and attention over every position at once." + }, + "ru": { + "title": "Память и внимание", + "line": "Сети, которые читают последовательность: рекуррентная ячейка и её затухающее эхо, вентили LSTM и внимание ко всем позициям сразу." + } + }, + { + "id": "transformer-and-reward", + "n": 9, + "lessons": [ + "positional-encoding", + "an-encoder-block", + "ppo-and-the-reward" + ], + "en": { + "title": "The transformer and the reward", + "line": "The parts of a transformer and of an agent: positions as clocks, one encoder block, and PPO, which learns from reward without lurching." + }, + "ru": { + "title": "Трансформер и награда", + "line": "Части трансформера и агента: позиции как часы, один блок энкодера и PPO, который учится на награде без рывков." + } + } + ], + "lessons": [ + { + "id": "relu", + "n": 1, + "module": "one-neuron", + "widget": { + "id": "nn-relu", + "kind": "tool", + "title": "ReLU: what a neuron does with a negative number", + "url": "https://t27.ai/widgets/nn-relu/", + "preview": "widgets/nn-relu/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-sigmoid", + "kind": "tool", + "title": "Sigmoid: turn any number into a probability", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-tanh", + "kind": "tool", + "title": "tanh: where a neuron stops learning", + "url": "https://t27.ai/widgets/nn-tanh/", + "preview": "widgets/nn-tanh/index.html?embed=1", + "height": 760 + }, + { + "id": "tc-one-neuron", + "kind": "tool", + "title": "One ternary neuron: inputs, weights, a threshold", + "url": "https://t27.ai/widgets/tc-one-neuron/", + "preview": "widgets/tc-one-neuron/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/relu_activation.t27", + "source": "t27/files/specs/ml/activation/relu_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Frelu_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "ReLU: keep the positive part", + "goal": "What ReLU does to a positive and to a negative input, and why a slope of 0 stops a unit from learning.", + "text": "A neuron adds up its weighted inputs and passes the sum through an activation. ReLU is the plainest one, max(0, x): a positive sum goes through unchanged and a negative one becomes 0. Its slope is 1 or 0, and a slope of 0 is a unit that has stopped learning, because no gradient flows back through it. A leaky slope fixes that: with a slope of 0.1, x = -2 gives -0.2 and passes back a gradient of 0.1. The spec relu_activation.t27 computes both curves the widget draws.", + "task": "Put x at -2 and read the slope with and without the leak; then find the slope at x = 1.5." + }, + "ru": { + "title": "ReLU: оставить положительную часть", + "goal": "Что ReLU делает с положительным и с отрицательным входом и почему наклон 0 останавливает обучение нейрона.", + "text": "Нейрон складывает взвешенные входы и пропускает сумму через функцию активации. ReLU из них самая простая, max(0, x): положительная сумма проходит без изменений, отрицательная становится 0. Её наклон равен 1 или 0, а наклон 0 означает нейрон, который перестал учиться: градиент через него назад не течёт. Утечка это исправляет: с наклоном 0.1 вход x = -2 даёт -0.2 и пропускает назад градиент 0.1. Спека relu_activation.t27 вычисляет обе кривые, которые рисует виджет.", + "task": "Поставьте x на -2 и прочитайте наклон с утечкой и без неё; затем найдите наклон при x = 1.5." + } + }, + { + "id": "the-sigmoid", + "n": 2, + "module": "one-neuron", + "widget": { + "id": "nn-sigmoid", + "kind": "tool", + "title": "Sigmoid: turn any number into a probability", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-relu", + "kind": "tool", + "title": "ReLU: what a neuron does with a negative number", + "url": "https://t27.ai/widgets/nn-relu/", + "preview": "widgets/nn-relu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-tanh", + "kind": "tool", + "title": "tanh: where a neuron stops learning", + "url": "https://t27.ai/widgets/nn-tanh/", + "preview": "widgets/nn-tanh/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-bce", + "kind": "tool", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "url": "https://t27.ai/widgets/nn-bce/", + "preview": "widgets/nn-bce/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/sigmoid_activation.t27", + "source": "t27/files/specs/ml/activation/sigmoid_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Fsigmoid_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "The sigmoid: a number into a probability", + "goal": "How the sigmoid maps any input to a probability, and why its slope limits deep networks.", + "text": "The sigmoid 1 / (1 + e^-x) squeezes the whole number line into 0 to 1, which is why it reads as a probability: 2 becomes 0.8808 and -4 becomes 0.018. Its slope is s (1 - s), computed from the output s itself, and it is largest at 0, where it is 0.25; at x = 8 it is 0.000335. A gradient that passes back through a stack of sigmoids is multiplied by at most 0.25 at each one, which is why deep sigmoid networks trained slowly. The spec sigmoid_activation.t27 computes the curve and the slope.", + "task": "Find the input where the probability is 0.5; then drag to 6 and read how little slope is left." + }, + "ru": { + "title": "Сигмоида: число в вероятность", + "goal": "Как сигмоида переводит любой вход в вероятность и почему её наклон мешает глубоким сетям.", + "text": "Сигмоида 1 / (1 + e^-x) сжимает всю числовую прямую в отрезок от 0 до 1, поэтому её читают как вероятность: 2 превращается в 0.8808, а -4 в 0.018. Её наклон равен s (1 - s) и считается по самому выходу s; он наибольший в 0, где равен 0.25, а при x = 8 равен 0.000335. Градиент, который идёт назад через стопку сигмоид, на каждой умножается не больше чем на 0.25, поэтому глубокие сети на сигмоидах учились медленно. Спека sigmoid_activation.t27 вычисляет кривую и наклон.", + "task": "Найдите вход, при котором вероятность равна 0.5; затем перетащите к 6 и посмотрите, как мало осталось наклона." + } + }, + { + "id": "tanh-and-saturation", + "n": 3, + "module": "one-neuron", + "widget": { + "id": "nn-tanh", + "kind": "tool", + "title": "tanh: where a neuron stops learning", + "url": "https://t27.ai/widgets/nn-tanh/", + "preview": "widgets/nn-tanh/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-relu", + "kind": "tool", + "title": "ReLU: what a neuron does with a negative number", + "url": "https://t27.ai/widgets/nn-relu/", + "preview": "widgets/nn-relu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-sigmoid", + "kind": "tool", + "title": "Sigmoid: turn any number into a probability", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/tanh_activation.t27", + "source": "t27/files/specs/ml/activation/tanh_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Ftanh_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "tanh and saturation", + "goal": "Why tanh is centred on zero, and where its slope falls so low that a unit stops learning.", + "text": "tanh is a sigmoid stretched to -1..1 and centred on 0, so a layer of tanh units passes on values that average near zero, and its slope reaches 1 at the centre. It still saturates: at 2.5 the output is 0.9866 and the slope only 0.0266. The red band marks every input where the slope is under 0.1, beyond about 1.8 on either side, and a unit whose inputs live there barely learns. The spec tanh_activation.t27 computes the curve, the slope and its own batch, tanh of 0, 1 and 2: 0, 0.762 and 0.964.", + "task": "Drag x until the band starts and read the slope there; then compare the slope at 0 and at 2.5." + }, + "ru": { + "title": "tanh и насыщение", + "goal": "Почему tanh центрирована на нуле и где её наклон падает так низко, что нейрон перестаёт учиться.", + "text": "tanh это сигмоида, растянутая на -1..1 и центрированная на 0, поэтому слой нейронов tanh передаёт дальше значения со средним около нуля, а её наклон в центре достигает 1. Она тоже насыщается: при 2.5 выход 0.9866, а наклон всего 0.0266. Красная полоса отмечает все входы, где наклон меньше 0.1, дальше примерно 1.8 в обе стороны, и нейрон, чьи входы живут там, почти не учится. Спека tanh_activation.t27 вычисляет кривую, наклон и свой пакет, tanh от 0, 1 и 2: 0, 0.762 и 0.964.", + "task": "Тяните x, пока не начнётся полоса, и прочитайте наклон там; затем сравните наклон в 0 и при 2.5." + } + }, + { + "id": "gelu", + "n": 4, + "module": "new-bends", + "widget": { + "id": "nn-gelu", + "kind": "tool", + "title": "GELU: why transformers bend a little below zero", + "url": "https://t27.ai/widgets/nn-gelu/", + "preview": "widgets/nn-gelu/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-silu", + "kind": "tool", + "title": "Swish: one knob between a smooth curve and ReLU", + "url": "https://t27.ai/widgets/nn-silu/", + "preview": "widgets/nn-silu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-elu", + "kind": "tool", + "title": "ELU: a negative side with a floor", + "url": "https://t27.ai/widgets/nn-elu/", + "preview": "widgets/nn-elu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/gelu_activation.t27", + "source": "t27/files/specs/ml/activation/gelu_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Fgelu_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "GELU: a dip below zero", + "goal": "What GELU computes, why it dips below zero, and how close its tanh shortcut comes.", + "text": "GELU weighs x by the chance that a standard normal draw is below it: GELU(x) = x Phi(x). A large positive input passes, a large negative one vanishes, and in between the curve dips to about -0.17 near x = -0.75 before it rises. BERT and GPT use it in their feed-forward layers. The exact form needs erf, which the spec computes with the Abramowitz-Stegun fit, good to 1.5e-7, and it also computes the tanh shortcut: at -0.75 they give -0.16997 and -0.17004. The spec gelu_activation.t27 computes both curves and their slopes.", + "task": "Find the lowest point of the curve by its slope; then compare the exact and the tanh form at -3." + }, + "ru": { + "title": "GELU: провал ниже нуля", + "goal": "Что вычисляет GELU, почему она проваливается ниже нуля и насколько близко подходит её приближение через tanh.", + "text": "GELU взвешивает x вероятностью того, что стандартная нормальная величина меньше него: GELU(x) = x Phi(x). Большой положительный вход проходит, большой отрицательный исчезает, а между ними кривая проваливается примерно до -0.17 около x = -0.75 и только потом растёт. BERT и GPT используют её в своих слоях прямого распространения. Точной форме нужна erf, и спека вычисляет её приближением Абрамовица-Стиган с точностью 1.5e-7, а также вычисляет приближение через tanh: при -0.75 они дают -0.16997 и -0.17004. Спека gelu_activation.t27 вычисляет обе кривые и их наклоны.", + "task": "Найдите нижнюю точку кривой по её наклону; затем сравните точную форму и форму через tanh при -3." + } + }, + { + "id": "swish-and-silu", + "n": 5, + "module": "new-bends", + "widget": { + "id": "nn-silu", + "kind": "tool", + "title": "Swish: one knob between a smooth curve and ReLU", + "url": "https://t27.ai/widgets/nn-silu/", + "preview": "widgets/nn-silu/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-gelu", + "kind": "tool", + "title": "GELU: why transformers bend a little below zero", + "url": "https://t27.ai/widgets/nn-gelu/", + "preview": "widgets/nn-gelu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-elu", + "kind": "tool", + "title": "ELU: a negative side with a floor", + "url": "https://t27.ai/widgets/nn-elu/", + "preview": "widgets/nn-elu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-relu", + "kind": "tool", + "title": "ReLU: what a neuron does with a negative number", + "url": "https://t27.ai/widgets/nn-relu/", + "preview": "widgets/nn-relu/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/silu_swish_activation.t27", + "source": "t27/files/specs/ml/activation/silu_swish_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Fsilu_swish_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Swish and SiLU", + "goal": "How x times sigmoid(beta x) gates itself, and how one parameter moves it from a smooth curve to ReLU.", + "text": "Swish is x times sigmoid(beta x), a unit that gates itself. At beta 1 it is called SiLU, and its lowest point is -0.2785 near x = -1.28. Raise beta and the gate sharpens: at beta 8 the curve is ReLU with rounded corners; at beta 0.5 it is a gentle slope through zero. One parameter moves the unit between a smooth curve and a switch, and a network can learn it. The spec silu_swish_activation.t27 computes the curve and its slope for any beta, and its own batch at -2, 0 and 2: -0.238, 0 and 1.762.", + "task": "Hold x at -1.28 and raise beta from 1 to 8; then find the beta at which the dip is gone at this scale." + }, + "ru": { + "title": "Swish и SiLU", + "goal": "Как x, умноженный на sigmoid(beta x), открывает сам себя и как один параметр переводит его от гладкой кривой к ReLU.", + "text": "Swish это x, умноженный на sigmoid(beta x): нейрон, который сам себе вентиль. При beta 1 он называется SiLU, и его нижняя точка -0.2785 около x = -1.28. Увеличьте beta, и вентиль становится резче: при beta 8 кривая это ReLU со скруглёнными углами, при beta 0.5 пологий склон через ноль. Один параметр переводит нейрон от гладкой кривой к переключателю, и сеть может его выучить. Спека silu_swish_activation.t27 вычисляет кривую и её наклон при любом beta, а также свой пакет при -2, 0 и 2: -0.238, 0 и 1.762.", + "task": "Держите x на -1.28 и поднимайте beta от 1 до 8; затем найдите beta, при котором провал на этом масштабе исчезает." + } + }, + { + "id": "elu", + "n": 6, + "module": "new-bends", + "widget": { + "id": "nn-elu", + "kind": "tool", + "title": "ELU: a negative side with a floor", + "url": "https://t27.ai/widgets/nn-elu/", + "preview": "widgets/nn-elu/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-relu", + "kind": "tool", + "title": "ReLU: what a neuron does with a negative number", + "url": "https://t27.ai/widgets/nn-relu/", + "preview": "widgets/nn-relu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-silu", + "kind": "tool", + "title": "Swish: one knob between a smooth curve and ReLU", + "url": "https://t27.ai/widgets/nn-silu/", + "preview": "widgets/nn-silu/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-gelu", + "kind": "tool", + "title": "GELU: why transformers bend a little below zero", + "url": "https://t27.ai/widgets/nn-gelu/", + "preview": "widgets/nn-gelu/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/elu_activation.t27", + "source": "t27/files/specs/ml/activation/elu_activation.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Felu_activation.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "ELU: a floor, not a cliff", + "goal": "How ELU keeps a soft negative side with a floor at -alpha, and why its slope never quite dies.", + "text": "ELU keeps the positive side of ReLU and replaces the cliff on the negative side with alpha (e^x - 1), a curve that flattens toward -alpha. With alpha 1, x = -3 gives -0.9502, already near the floor of -1, and the slope there is 0.0498: small, but not 0, so the unit can still move. Because the negative outputs are not thrown away, a layer's outputs average closer to 0. The spec elu_activation.t27 computes the curve, the slope and the floor, and its own batch at -1, 0 and 2: -0.632, 0 and 2.", + "task": "Set alpha to 0.5 and read the floor; then find how far left x must go before the slope is under 0.01." + }, + "ru": { + "title": "ELU: пол, а не обрыв", + "goal": "Как ELU сохраняет мягкую отрицательную сторону с полом на -alpha и почему её наклон никогда не умирает до конца.", + "text": "ELU сохраняет положительную сторону ReLU и заменяет обрыв на отрицательной стороне кривой alpha (e^x - 1), которая выполаживается к -alpha. При alpha 1 вход x = -3 даёт -0.9502, уже близко к полу -1, а наклон там 0.0498: мал, но не 0, так что нейрон ещё может сдвинуться. Отрицательные выходы не выбрасываются, поэтому среднее выходов слоя ближе к 0. Спека elu_activation.t27 вычисляет кривую, наклон и пол, а также свой пакет при -1, 0 и 2: -0.632, 0 и 2.", + "task": "Поставьте alpha на 0.5 и прочитайте пол; затем найдите, как далеко влево должен уйти x, чтобы наклон стал меньше 0.01." + } + }, + { + "id": "softmax-and-temperature", + "n": 7, + "module": "a-layer", + "widget": { + "id": "nn-softmax", + "kind": "tool", + "title": "Softmax: how a network turns scores into a choice", + "url": "https://t27.ai/widgets/nn-softmax/", + "preview": "widgets/nn-softmax/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-embedding", + "kind": "tool", + "title": "Embeddings: how a word becomes a row of numbers", + "url": "https://t27.ai/widgets/nn-embedding/", + "preview": "widgets/nn-embedding/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-dropout", + "kind": "tool", + "title": "Dropout: training a network with neurons switched off", + "url": "https://t27.ai/widgets/nn-dropout/", + "preview": "widgets/nn-dropout/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-bce", + "kind": "tool", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "url": "https://t27.ai/widgets/nn-bce/", + "preview": "widgets/nn-bce/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/activation/softmax.t27", + "source": "t27/files/specs/ml/activation/softmax.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Factivation%2Fsoftmax.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Softmax and temperature", + "goal": "How softmax turns scores into probabilities that sum to one, and what the temperature does to them.", + "text": "A classifier ends with one score per class, and softmax turns the scores into probabilities: exp of each score over the sum of all of them. Scores 1, 2 and 3 become 0.090, 0.245 and 0.665. Dividing the scores by a temperature first changes how sure it is: at 0.5 the top score takes 0.867, at 5 the three are 0.27, 0.33 and 0.40. A language model picks its next token from exactly this, and the temperature setting of a chat model is this T. The spec softmax.t27 subtracts the largest score first, so exp never overflows.", + "task": "Cool the temperature to 0.1 and read the three probabilities; then make a tie and heat it." + }, + "ru": { + "title": "Softmax и температура", + "goal": "Как softmax превращает оценки в вероятности с суммой один и что с ними делает температура.", + "text": "Классификатор заканчивается одной оценкой на класс, и softmax превращает оценки в вероятности: exp каждой оценки, делённая на сумму всех. Оценки 1, 2 и 3 становятся 0.090, 0.245 и 0.665. Если сначала разделить оценки на температуру, меняется уверенность: при 0.5 верхняя оценка забирает 0.867, при 5 все три равны 0.27, 0.33 и 0.40. Языковая модель выбирает следующий токен именно отсюда, и настройка температуры чат-модели это и есть T. Спека softmax.t27 сначала вычитает наибольшую оценку, поэтому exp никогда не переполняется.", + "task": "Охладите температуру до 0.1 и прочитайте три вероятности; затем сделайте ничью и нагрейте её." + } + }, + { + "id": "embeddings", + "n": 8, + "module": "a-layer", + "widget": { + "id": "nn-embedding", + "kind": "tool", + "title": "Embeddings: how a word becomes a row of numbers", + "url": "https://t27.ai/widgets/nn-embedding/", + "preview": "widgets/nn-embedding/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-softmax", + "kind": "tool", + "title": "Softmax: how a network turns scores into a choice", + "url": "https://t27.ai/widgets/nn-softmax/", + "preview": "widgets/nn-softmax/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-dropout", + "kind": "tool", + "title": "Dropout: training a network with neurons switched off", + "url": "https://t27.ai/widgets/nn-dropout/", + "preview": "widgets/nn-dropout/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-positions", + "kind": "tool", + "title": "Positional encoding: how a transformer knows word order", + "url": "https://t27.ai/widgets/nn-positions/", + "preview": "widgets/nn-positions/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/embedding_layer.t27", + "source": "t27/files/specs/ml/layers/embedding_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Fembedding_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Embeddings", + "goal": "How a token becomes a row of numbers, and why learning changes only the rows that were read.", + "text": "A network cannot multiply a word, so each token is an index into a table with one row of numbers per token, and looking a token up copies its row. In the spec the table has 4 tokens of width 2 and row v holds (10 v, 10 v + 1), so token 2 reads (20, 21). Learning sends the gradient back only to the rows that were read, and a token read twice collects both: gradient rows (1, 2) and (3, 4) on token 2 add up to (4, 6). The spec embedding_layer.t27 computes the lookup and the gradient.", + "task": "Read token 2 twice and then tokens 1 and 3; count the rows whose gradient is not 0 each time." + }, + "ru": { + "title": "Эмбеддинги", + "goal": "Как токен превращается в строку чисел и почему обучение меняет только прочитанные строки.", + "text": "Сеть не умеет умножать слово, поэтому каждый токен это индекс в таблице с одной строкой чисел на токен, а поиск токена копирует его строку. В спеке в таблице 4 токена шириной 2, и строка v хранит (10 v, 10 v + 1), так что токен 2 читает (20, 21). Обучение отправляет градиент назад только в прочитанные строки, а токен, прочитанный дважды, собирает оба: строки градиента (1, 2) и (3, 4) на токене 2 складываются в (4, 6). Спека embedding_layer.t27 вычисляет поиск и градиент.", + "task": "Прочитайте токен 2 дважды, а затем токены 1 и 3; каждый раз сосчитайте строки, где градиент не 0." + } + }, + { + "id": "dropout", + "n": 9, + "module": "a-layer", + "widget": { + "id": "nn-dropout", + "kind": "tool", + "title": "Dropout: training a network with neurons switched off", + "url": "https://t27.ai/widgets/nn-dropout/", + "preview": "widgets/nn-dropout/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-softmax", + "kind": "tool", + "title": "Softmax: how a network turns scores into a choice", + "url": "https://t27.ai/widgets/nn-softmax/", + "preview": "widgets/nn-softmax/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-embedding", + "kind": "tool", + "title": "Embeddings: how a word becomes a row of numbers", + "url": "https://t27.ai/widgets/nn-embedding/", + "preview": "widgets/nn-embedding/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/dropout_layer.t27", + "source": "t27/files/specs/ml/layers/dropout_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Fdropout_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Dropout", + "goal": "Why switching units off while training helps, and why the survivors must be scaled.", + "text": "While training, dropout switches off a share p of the units at random, so the rest cannot lean on any one of them. The units that survive must then be scaled, or the next layer would see the signal at another size in training than at inference. Inverted dropout scales them by 1 / (1 - p) while training: with p = 0.5, input 1, 2, 3, 4 becomes 2, 0, 6, 0, and inference is a plain pass. Classic dropout keeps 1, 0, 3, 0 and scales by 0.5 at inference instead. The spec dropout_layer.t27 uses a fixed mask, keep, drop, keep, drop, so the numbers are the same every time.", + "task": "Compare the outputs of the four modes; then read the gradient of a dropped unit in training." + }, + "ru": { + "title": "Dropout: выключенные нейроны", + "goal": "Почему выключение нейронов во время обучения помогает и почему выживших нужно масштабировать.", + "text": "Во время обучения dropout случайно выключает долю p нейронов, чтобы остальные не опирались ни на один из них. Выжившие нейроны тогда нужно масштабировать, иначе следующий слой видел бы сигнал другого размера при обучении, чем при выводе. Обратный dropout умножает их на 1 / (1 - p) при обучении: с p = 0.5 вход 1, 2, 3, 4 становится 2, 0, 6, 0, а вывод это простой проход. Классический dropout оставляет 1, 0, 3, 0 и умножает на 0.5 уже при выводе. Спека dropout_layer.t27 использует фиксированную маску, оставить, выбросить, оставить, выбросить, поэтому числа каждый раз одинаковые.", + "task": "Сравните выходы четырёх режимов; затем прочитайте градиент выброшенного нейрона при обучении." + } + }, + { + "id": "patches-of-a-picture", + "n": 10, + "module": "pictures", + "widget": { + "id": "nn-conv", + "kind": "tool", + "title": "Patches of a picture: a 2 x 2 window, averaged", + "url": "https://t27.ai/widgets/nn-conv/", + "preview": "widgets/nn-conv/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-maxpool", + "kind": "tool", + "title": "Max pooling: what a network keeps when it shrinks a picture", + "url": "https://t27.ai/widgets/nn-maxpool/", + "preview": "widgets/nn-maxpool/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-batchnorm", + "kind": "tool", + "title": "Batch norm: features on very different scales, made comparable", + "url": "https://t27.ai/widgets/nn-batchnorm/", + "preview": "widgets/nn-batchnorm/index.html?embed=1", + "height": 760 + }, + { + "id": "tc-detector", + "kind": "tool", + "title": "A bar detector: one neuron, four patterns", + "url": "https://t27.ai/widgets/tc-detector/", + "preview": "widgets/tc-detector/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/avgpool2d_layer.t27", + "source": "t27/files/specs/ml/layers/avgpool2d_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Favgpool2d_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Patches of a picture", + "goal": "Why networks read a picture in patches, and what a 2 x 2 window averaged over each patch gives.", + "text": "A picture is a grid of numbers, and networks read it in small patches so that the same detector works anywhere in it. Here a 2 x 2 window steps by 2 over a 4 x 4 image whose cell i holds i, and each output is the average of its patch: 2.5, 4.5, 10.5 and 12.5. In the backward pass each output's gradient is split equally over its 4 cells. This is average pooling: a convolution would weight the 4 cells with a learned kernel, and its spec, t27#10612, is not merged yet. The spec avgpool2d_layer.t27 computes both passes.", + "task": "Tap each patch and check its average by eye; then switch to the gradient and read what each cell of window 4 receives." + }, + "ru": { + "title": "Участки картинки", + "goal": "Почему сети читают картинку по участкам и что даёт окно 2 x 2, усреднённое по каждому участку.", + "text": "Картинка это сетка чисел, и сети читают её небольшими участками, чтобы один и тот же детектор работал в любом её месте. Здесь окно 2 x 2 шагает по 2 по картинке 4 x 4, где в клетке i лежит i, и каждый выход это среднее своего участка: 2.5, 4.5, 10.5 и 12.5. При обратном проходе градиент каждого выхода делится поровну на его 4 клетки. Это усредняющий пулинг: свёртка взвешивала бы 4 клетки выученным ядром, и её спека, t27#10612, ещё не слита. Спека avgpool2d_layer.t27 вычисляет оба прохода.", + "task": "Нажмите на каждый участок и проверьте его среднее на глаз; затем включите градиент и прочитайте, что получает каждая клетка окна 4." + } + }, + { + "id": "max-pooling", + "n": 11, + "module": "pictures", + "widget": { + "id": "nn-maxpool", + "kind": "tool", + "title": "Max pooling: what a network keeps when it shrinks a picture", + "url": "https://t27.ai/widgets/nn-maxpool/", + "preview": "widgets/nn-maxpool/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-conv", + "kind": "tool", + "title": "Patches of a picture: a 2 x 2 window, averaged", + "url": "https://t27.ai/widgets/nn-conv/", + "preview": "widgets/nn-conv/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-batchnorm", + "kind": "tool", + "title": "Batch norm: features on very different scales, made comparable", + "url": "https://t27.ai/widgets/nn-batchnorm/", + "preview": "widgets/nn-batchnorm/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/maxpool2d_layer.t27", + "source": "t27/files/specs/ml/layers/maxpool2d_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Fmaxpool2d_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Max pooling", + "goal": "What max pooling keeps, where it remembers taking it from, and where the gradient goes.", + "text": "Max pooling keeps the largest value of each window and drops the rest, so the network cares less about exactly where a feature sits. On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2, taken from cells 5, 6, 13 and 11. Overlapping 3 x 3 windows with stride 1 keep 8, 8, 9 and 9. In the backward pass each window's whole gradient goes to its maximum: gradients 1, 2, 3 and 4 land on cells 5, 6, 13 and 11, and every other cell gets 0. The spec maxpool2d_layer.t27 computes the outputs, their positions and the gradient.", + "task": "Switch to 3 x 3 windows and find the cell two outputs share; then turn on the gradient for 2 x 2 windows." + }, + "ru": { + "title": "Max pooling: максимум окна", + "goal": "Что оставляет max pooling, откуда, как он помнит, это взято и куда идёт градиент.", + "text": "Max pooling оставляет наибольшее значение каждого окна и отбрасывает остальные, поэтому сети становится менее важно, где именно лежит признак. На сетке спеки 4 x 4 окна 2 x 2 с шагом 2 оставляют 4, 8, 9 и -2, взятые из клеток 5, 6, 13 и 11. Перекрывающиеся окна 3 x 3 с шагом 1 оставляют 8, 8, 9 и 9. При обратном проходе весь градиент окна идёт в его максимум: градиенты 1, 2, 3 и 4 попадают в клетки 5, 6, 13 и 11, а все остальные клетки получают 0. Спека maxpool2d_layer.t27 вычисляет выходы, их позиции и градиент.", + "task": "Переключитесь на окна 3 x 3 и найдите клетку, общую для двух выходов; затем включите градиент для окон 2 x 2." + } + }, + { + "id": "batch-normalisation", + "n": 12, + "module": "pictures", + "widget": { + "id": "nn-batchnorm", + "kind": "tool", + "title": "Batch norm: features on very different scales, made comparable", + "url": "https://t27.ai/widgets/nn-batchnorm/", + "preview": "widgets/nn-batchnorm/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-conv", + "kind": "tool", + "title": "Patches of a picture: a 2 x 2 window, averaged", + "url": "https://t27.ai/widgets/nn-conv/", + "preview": "widgets/nn-conv/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-maxpool", + "kind": "tool", + "title": "Max pooling: what a network keeps when it shrinks a picture", + "url": "https://t27.ai/widgets/nn-maxpool/", + "preview": "widgets/nn-maxpool/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/batchnorm_layer.t27", + "source": "t27/files/specs/ml/layers/batchnorm_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Fbatchnorm_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Batch normalisation", + "goal": "How batch norm puts features on different scales on one scale, and what it uses at inference.", + "text": "Features on different scales pull a network around: in the spec's batch one feature is ten times another. Batch normalisation subtracts each feature's batch mean and divides by its spread, so the features 1, 2, 3, 4 and 10, 20, 30, 40 both come out as -1.34, -0.45, 0.45 and 1.34, and -1, -1, 1, 1 comes out as -1 and 1. A learned gamma and beta then scale and shift it back where that helps. At inference the layer uses running averages instead of the batch: with mean 0, variance 1, gamma 1 and beta 0.25, the inputs 1, 2 and 3 give 1.25, 2.25 and 3.25. The spec batchnorm_layer.t27 computes both.", + "task": "Compare the two normalised columns; then set the running mean 2 and variance 4 and read the inference outputs." + }, + "ru": { + "title": "Пакетная нормализация", + "goal": "Как пакетная нормализация приводит признаки разного масштаба к одному и чем она пользуется при выводе.", + "text": "Признаки разного масштаба дёргают сеть: в пакете спеки один признак в десять раз больше другого. Пакетная нормализация вычитает среднее каждого признака по пакету и делит на его разброс, поэтому признаки 1, 2, 3, 4 и 10, 20, 30, 40 оба выходят как -1.34, -0.45, 0.45 и 1.34, а -1, -1, 1, 1 выходит как -1 и 1. Затем выученные gamma и beta масштабируют и сдвигают его обратно, где это полезно. При выводе слой вместо пакета использует скользящие средние: при среднем 0, дисперсии 1, gamma 1 и beta 0.25 входы 1, 2 и 3 дают 1.25, 2.25 и 3.25. Спека batchnorm_layer.t27 вычисляет оба режима.", + "task": "Сравните два нормализованных столбца; затем поставьте скользящее среднее 2 и дисперсию 4 и прочитайте выходы вывода." + } + }, + { + "id": "mean-squared-error", + "n": 13, + "module": "the-error", + "widget": { + "id": "nn-mse", + "kind": "tool", + "title": "Mean squared error: how wrong a guess is, as one number", + "url": "https://t27.ai/widgets/nn-mse/", + "preview": "widgets/nn-mse/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-bce", + "kind": "tool", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "url": "https://t27.ai/widgets/nn-bce/", + "preview": "widgets/nn-bce/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-huber", + "kind": "tool", + "title": "Huber loss: a loss that does not panic at an outlier", + "url": "https://t27.ai/widgets/nn-huber/", + "preview": "widgets/nn-huber/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/loss/mse_loss.t27", + "source": "t27/files/specs/ml/loss/mse_loss.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Floss%2Fmse_loss.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Mean squared error", + "goal": "How MSE turns every miss into one number, why it chases large errors, and where its gradient points.", + "text": "A loss turns all the misses of a model into one number to push down. Mean squared error averages the squared misses: predictions 1.5, 2 and 2 against targets 1, 2 and 3 cost (0.25 + 0 + 1) / 3 = 0.4167. Squaring makes a miss of 2 cost 4 times a miss of 1, so MSE chases large errors. Its gradient for each prediction is 2 (p - t) / n, here 0.333, 0 and -0.667: each prediction is pushed back toward its target. As a function of one prediction the loss is a parabola, a bowl with one bottom. The spec mse_loss.t27 computes the loss and the gradient.", + "task": "Move prediction 2 onto its target and read the loss; then drag along the bowl and find its bottom." + }, + "ru": { + "title": "Среднеквадратичная ошибка", + "goal": "Как MSE превращает каждый промах в одно число, почему она гоняется за большими ошибками и куда смотрит её градиент.", + "text": "Функция потерь превращает все промахи модели в одно число, которое нужно уменьшать. Среднеквадратичная ошибка усредняет квадраты промахов: предсказания 1.5, 2 и 2 против целей 1, 2 и 3 стоят (0.25 + 0 + 1) / 3 = 0.4167. Из-за квадрата промах на 2 стоит в 4 раза больше промаха на 1, поэтому MSE гоняется за большими ошибками. Её градиент для каждого предсказания равен 2 (p - t) / n, здесь 0.333, 0 и -0.667: каждое предсказание толкается обратно к своей цели. Как функция одного предсказания потеря это парабола, чаша с одним дном. Спека mse_loss.t27 вычисляет потерю и градиент.", + "task": "Передвиньте предсказание 2 на его цель и прочитайте потерю; затем ведите по чаше и найдите её дно." + } + }, + { + "id": "cross-entropy", + "n": 14, + "module": "the-error", + "widget": { + "id": "nn-bce", + "kind": "tool", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "url": "https://t27.ai/widgets/nn-bce/", + "preview": "widgets/nn-bce/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-mse", + "kind": "tool", + "title": "Mean squared error: how wrong a guess is, as one number", + "url": "https://t27.ai/widgets/nn-mse/", + "preview": "widgets/nn-mse/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-huber", + "kind": "tool", + "title": "Huber loss: a loss that does not panic at an outlier", + "url": "https://t27.ai/widgets/nn-huber/", + "preview": "widgets/nn-huber/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-sigmoid", + "kind": "tool", + "title": "Sigmoid: turn any number into a probability", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/loss/binary_crossentropy_loss.t27", + "source": "t27/files/specs/ml/loss/binary_crossentropy_loss.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Floss%2Fbinary_crossentropy_loss.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Cross-entropy", + "goal": "Why cross-entropy charges a confident wrong answer so much, and why that is what trains a classifier.", + "text": "A classifier outputs a probability, and cross-entropy charges -log of the probability it gave to the true answer. Predictions 0.8, 0.3 and 0.9 against answers 1, 0 and 1 cost 0.2284 on average. Being sure and right is nearly free: 0.99, 0.01 and 0.99 cost 0.0101. Being sure and wrong is expensive: 0.01, 0.99 and 0.01 cost 4.6052, and toward 0 the cost grows without bound, which is why the spec clips p to [1e-7, 1 - 1e-7]. Its gradient is largest exactly where the model is sure and wrong. The spec binary_crossentropy_loss.t27 computes the loss and the gradient, from probabilities or from logits.", + "task": "Drag prediction 0 toward 0.01 and watch the curve; then read the gradient bars at 0.5, 0.5 and 0.5." + }, + "ru": { + "title": "Перекрёстная энтропия", + "goal": "Почему перекрёстная энтропия так дорого берёт за уверенный неверный ответ и почему именно это учит классификатор.", + "text": "Классификатор выдаёт вероятность, а перекрёстная энтропия берёт -log вероятности, которую он дал верному ответу. Предсказания 0.8, 0.3 и 0.9 против ответов 1, 0 и 1 стоят в среднем 0.2284. Быть уверенным и правым почти бесплатно: 0.99, 0.01 и 0.99 стоят 0.0101. Быть уверенным и неправым дорого: 0.01, 0.99 и 0.01 стоят 4.6052, а к 0 стоимость растёт без предела, поэтому спека обрезает p до [1e-7, 1 - 1e-7]. Её градиент наибольший как раз там, где модель уверена и неправа. Спека binary_crossentropy_loss.t27 вычисляет потерю и градиент, из вероятностей или из логитов.", + "task": "Тяните предсказание 0 к 0.01 и смотрите на кривую; затем прочитайте столбики градиента при 0.5, 0.5 и 0.5." + } + }, + { + "id": "the-huber-loss", + "n": 15, + "module": "the-error", + "widget": { + "id": "nn-huber", + "kind": "tool", + "title": "Huber loss: a loss that does not panic at an outlier", + "url": "https://t27.ai/widgets/nn-huber/", + "preview": "widgets/nn-huber/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-mse", + "kind": "tool", + "title": "Mean squared error: how wrong a guess is, as one number", + "url": "https://t27.ai/widgets/nn-mse/", + "preview": "widgets/nn-mse/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-bce", + "kind": "tool", + "title": "Cross-entropy: why a confident wrong answer costs so much", + "url": "https://t27.ai/widgets/nn-bce/", + "preview": "widgets/nn-bce/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/loss/huber_loss.t27", + "source": "t27/files/specs/ml/loss/huber_loss.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Floss%2Fhuber_loss.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "The Huber loss", + "goal": "How the Huber loss treats a small error like squared error and a large one linearly, so outliers pull less.", + "text": "Squared error lets one outlier dominate: an error of 3 costs 4.5 as half its square, as much as 36 errors of 0.5. Huber is half the square while |e| is within delta and then grows only linearly, delta |e| - delta^2 / 2, so with delta 1 that error costs 2.5. The two pieces meet with the same value and slope, and the gradient never grows past delta: a far-off point pulls on the model with a bounded force. For the spec's pair of errors 0.5 and 3 the mean is 1.3125, against 2.3125 for half the square. The spec huber_loss.t27 computes both.", + "task": "Set delta to 0.5 and drag the error to 3; then find where the two curves part." + }, + "ru": { + "title": "Функция Хьюбера", + "goal": "Как функция Хьюбера обходится с малой ошибкой как с квадратичной, а с большой линейно, чтобы выбросы тянули слабее.", + "text": "Квадратичная ошибка позволяет одному выбросу всё решать: ошибка 3 стоит 4.5 как половина своего квадрата, столько же, сколько 36 ошибок по 0.5. Функция Хьюбера равна половине квадрата, пока |e| не больше delta, а дальше растёт только линейно, delta |e| - delta^2 / 2, так что при delta 1 та же ошибка стоит 2.5. Два куска сходятся с одинаковым значением и наклоном, и градиент никогда не превышает delta: далёкая точка тянет модель с ограниченной силой. Для пары ошибок спеки 0.5 и 3 среднее равно 1.3125 против 2.3125 для половины квадрата. Спека huber_loss.t27 вычисляет обе.", + "task": "Поставьте delta на 0.5 и тяните ошибку к 3; затем найдите, где две кривые расходятся." + } + }, + { + "id": "gradient-descent", + "n": 16, + "module": "downhill", + "widget": { + "id": "nn-sgd", + "kind": "tool", + "title": "Gradient descent: how a network walks downhill", + "url": "https://t27.ai/widgets/nn-sgd/", + "preview": "widgets/nn-sgd/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-rmsprop", + "kind": "tool", + "title": "RMSProp: a step that does not care how big the gradient is", + "url": "https://t27.ai/widgets/nn-rmsprop/", + "preview": "widgets/nn-rmsprop/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-adam", + "kind": "tool", + "title": "Adam: the optimizer most networks are trained with", + "url": "https://t27.ai/widgets/nn-adam/", + "preview": "widgets/nn-adam/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-mse", + "kind": "tool", + "title": "Mean squared error: how wrong a guess is, as one number", + "url": "https://t27.ai/widgets/nn-mse/", + "preview": "widgets/nn-mse/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/optimizer/sgd.t27", + "source": "t27/files/specs/ml/optimizer/sgd.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Foptimizer%2Fsgd.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Gradient descent", + "goal": "How gradient descent walks down a loss, what momentum adds, and why too large a rate never settles.", + "text": "Training is walking downhill on the loss. Gradient descent moves a weight by -lr times its gradient each step; in the spec the loss is (x - 3)^2 from x = 0, and lr 0.1 reaches 2.99996 in 50 steps. Momentum adds a share of the last move, which speeds up a long slope and overshoots a sharp bottom: at 0.9 the weight shoots past 3 to about 5.13 and rings down to 3.09 after 50 steps. Nesterov takes the gradient one step ahead and swings less, to about 4.25. Too large a rate never settles: at lr 1 the weight bounces between 0 and 6 for good. The spec sgd.t27 computes every step.", + "task": "Find the largest learning rate that still settles without momentum; then add momentum 0.9 and count the swings." + }, + "ru": { + "title": "Градиентный спуск", + "goal": "Как градиентный спуск идёт вниз по функции потерь, что добавляет момент и почему слишком большой шаг никогда не успокаивается.", + "text": "Обучение это спуск под гору по функции потерь. Градиентный спуск каждый шаг сдвигает вес на -lr, умноженное на его градиент; в спеке потеря равна (x - 3)^2 от x = 0, и lr 0.1 доходит до 2.99996 за 50 шагов. Момент добавляет долю прошлого сдвига, что ускоряет длинный склон и перелетает острое дно: при 0.9 вес пролетает 3 примерно до 5.13 и, раскачиваясь, приходит к 3.09 после 50 шагов. Нестеров берёт градиент на шаг вперёд и качается меньше, примерно до 4.25. Слишком большой шаг никогда не успокаивается: при lr 1 вес навсегда скачет между 0 и 6. Спека sgd.t27 вычисляет каждый шаг.", + "task": "Найдите наибольший шаг обучения, который ещё успокаивается без момента; затем добавьте момент 0.9 и сосчитайте качания." + } + }, + { + "id": "rmsprop", + "n": 17, + "module": "downhill", + "widget": { + "id": "nn-rmsprop", + "kind": "tool", + "title": "RMSProp: a step that does not care how big the gradient is", + "url": "https://t27.ai/widgets/nn-rmsprop/", + "preview": "widgets/nn-rmsprop/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-sgd", + "kind": "tool", + "title": "Gradient descent: how a network walks downhill", + "url": "https://t27.ai/widgets/nn-sgd/", + "preview": "widgets/nn-sgd/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-adam", + "kind": "tool", + "title": "Adam: the optimizer most networks are trained with", + "url": "https://t27.ai/widgets/nn-adam/", + "preview": "widgets/nn-adam/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/optimizer/rmsprop.t27", + "source": "t27/files/specs/ml/optimizer/rmsprop.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Foptimizer%2Frmsprop.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "RMSProp", + "goal": "How RMSProp divides each step by a running root mean square, so the step no longer depends on the gradient's size.", + "text": "The right step size depends on the size of the gradient, and different weights see gradients a million times apart. RMSProp keeps a running mean of the squared gradient, the cache, and divides each step by its root, so the step has no units: with a constant gradient of 0.001, 0.5 or 1000 the weight moves by exactly the same 0.0316 on step 1 and walks the same path, reaching -0.0914 after 100 steps at lr 0.01. The decay sets how slowly the cache fills: at 0.99 the same 100 steps end at -1.0261. The spec rmsprop.t27 computes the weight and the cache.", + "task": "Switch between the three gradients and check that the lines do not move; then raise the decay to 0.99." + }, + "ru": { + "title": "RMSProp: шаг без масштаба", + "goal": "Как RMSProp делит каждый шаг на скользящий корень среднего квадрата, чтобы шаг больше не зависел от величины градиента.", + "text": "Правильный размер шага зависит от величины градиента, а разные веса видят градиенты, отличающиеся в миллион раз. RMSProp хранит скользящее среднее квадрата градиента, кэш, и делит каждый шаг на его корень, поэтому у шага нет единиц: при постоянном градиенте 0.001, 0.5 или 1000 вес на шаге 1 сдвигается ровно на те же 0.0316 и идёт тем же путём, доходя до -0.0914 после 100 шагов при lr 0.01. Затухание задаёт, как медленно наполняется кэш: при 0.99 те же 100 шагов заканчиваются на -1.0261. Спека rmsprop.t27 вычисляет вес и кэш.", + "task": "Переключайтесь между тремя градиентами и убедитесь, что линии не двигаются; затем поднимите затухание до 0.99." + } + }, + { + "id": "adam", + "n": 18, + "module": "downhill", + "widget": { + "id": "nn-adam", + "kind": "tool", + "title": "Adam: the optimizer most networks are trained with", + "url": "https://t27.ai/widgets/nn-adam/", + "preview": "widgets/nn-adam/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-sgd", + "kind": "tool", + "title": "Gradient descent: how a network walks downhill", + "url": "https://t27.ai/widgets/nn-sgd/", + "preview": "widgets/nn-sgd/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-rmsprop", + "kind": "tool", + "title": "RMSProp: a step that does not care how big the gradient is", + "url": "https://t27.ai/widgets/nn-rmsprop/", + "preview": "widgets/nn-rmsprop/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-lamb", + "kind": "tool", + "title": "LAMB: one learning rate for layers of every size", + "url": "https://t27.ai/widgets/nn-lamb/", + "preview": "widgets/nn-lamb/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/optimizer/adam.t27", + "source": "t27/files/specs/ml/optimizer/adam.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Foptimizer%2Fadam.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Adam", + "goal": "How Adam combines momentum with a running scale, and why its bias correction makes step 1 a fixed size.", + "text": "Adam combines the two ideas: m, a running mean of the gradient, as in momentum, and v, a running mean of its square, as in RMSProp; the step is lr m / sqrt(v). Both start at 0 and are too small early on, so Adam divides them by 1 - beta^t, and on step 1 that makes the move exactly lr times the sign of the gradient: gradients 2, -40 and 0.5 all move their weights by 0.001. On the spec's bowl (x - 3)^2 at lr 0.1, Adam rises from 0, overshoots to about 3.18 and settles at 3.00005 by step 200. The spec adam.t27 computes every step.", + "task": "Give the three gradients very different sizes and read the weights after step 1; then find where the path tops out." + }, + "ru": { + "title": "Adam: момент и масштаб", + "goal": "Как Adam соединяет момент со скользящим масштабом и почему поправка смещения делает шаг 1 фиксированного размера.", + "text": "Adam соединяет обе идеи: m, скользящее среднее градиента, как в моменте, и v, скользящее среднее его квадрата, как в RMSProp; шаг равен lr m / sqrt(v). Оба начинают с 0 и поначалу слишком малы, поэтому Adam делит их на 1 - beta^t, и на шаге 1 это делает сдвиг ровно lr, умноженным на знак градиента: градиенты 2, -40 и 0.5 сдвигают свои веса на одинаковые 0.001. На чаше спеки (x - 3)^2 при lr 0.1 Adam поднимается от 0, перелетает примерно до 3.18 и успокаивается на 3.00005 к шагу 200. Спека adam.t27 вычисляет каждый шаг.", + "task": "Дайте трём градиентам очень разные размеры и прочитайте веса после шага 1; затем найдите, где путь достигает вершины." + } + }, + { + "id": "backpropagation", + "n": 19, + "module": "learning", + "widget": { + "id": "nn-backprop", + "kind": "tool", + "title": "Backpropagation: how blame flows back through a layer", + "url": "https://t27.ai/widgets/nn-backprop/", + "preview": "widgets/nn-backprop/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-xor", + "kind": "tool", + "title": "XOR: a network learns what one neuron cannot", + "url": "https://t27.ai/widgets/nn-xor/", + "preview": "widgets/nn-xor/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-lamb", + "kind": "tool", + "title": "LAMB: one learning rate for layers of every size", + "url": "https://t27.ai/widgets/nn-lamb/", + "preview": "widgets/nn-lamb/index.html?embed=1", + "height": 760 + }, + { + "id": "tc-tiny-layer", + "kind": "tool", + "title": "A layer of three ternary neurons", + "url": "https://t27.ai/widgets/tc-tiny-layer/", + "preview": "widgets/tc-tiny-layer/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/layers/dense_layer.t27", + "source": "t27/files/specs/ml/layers/dense_layer.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Flayers%2Fdense_layer.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Backpropagation", + "goal": "How the gradient of each weight and each input of a layer follows from the gradient of its outputs.", + "text": "To learn, every weight needs to know how the loss changes when it moves. Backpropagation answers one layer at a time: given g, how much the loss wants each output to move, the weight from input i to output o gets g_o x_i, and input i gets the sum over o of W[o][i] g_o, which it hands on to the layer below. With inputs (1, 2, 3) and g = (1, 0.5) the weight gradients are 1, 2, 3 and 0.5, 1, 1.5, and the input gradients 0.5, 2 and 3.5. The layer is linear, so moving x0 by 1 moves the loss g . y from 15.25 to 15.75, by its gradient 0.5. The spec dense_layer.t27 computes all three.", + "task": "Set g = (1, 0) and read which edges go dark; then set g = (-2, 1) and check the input gradients by hand." + }, + "ru": { + "title": "Обратное распространение", + "goal": "Как градиент каждого веса и каждого входа слоя следует из градиента его выходов.", + "text": "Чтобы учиться, каждому весу нужно знать, как меняется потеря, когда он сдвигается. Обратное распространение отвечает по одному слою за раз: при данном g, насколько потеря хочет сдвинуть каждый выход, вес от входа i к выходу o получает g_o x_i, а вход i получает сумму по o от W[o][i] g_o и передаёт её слою ниже. При входах (1, 2, 3) и g = (1, 0.5) градиенты весов равны 1, 2, 3 и 0.5, 1, 1.5, а градиенты входов 0.5, 2 и 3.5. Слой линейный, поэтому сдвиг x0 на 1 сдвигает потерю g . y с 15.25 до 15.75, на его градиент 0.5. Спека dense_layer.t27 вычисляет все три.", + "task": "Поставьте g = (1, 0) и посмотрите, какие рёбра гаснут; затем поставьте g = (-2, 1) и проверьте градиенты входов вручную." + } + }, + { + "id": "learning-xor", + "n": 20, + "module": "learning", + "widget": { + "id": "nn-xor", + "kind": "tool", + "title": "XOR: a network learns what one neuron cannot", + "url": "https://t27.ai/widgets/nn-xor/", + "preview": "widgets/nn-xor/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-backprop", + "kind": "tool", + "title": "Backpropagation: how blame flows back through a layer", + "url": "https://t27.ai/widgets/nn-backprop/", + "preview": "widgets/nn-backprop/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-lamb", + "kind": "tool", + "title": "LAMB: one learning rate for layers of every size", + "url": "https://t27.ai/widgets/nn-lamb/", + "preview": "widgets/nn-lamb/index.html?embed=1", + "height": 760 + }, + { + "id": "tc-tiny-layer", + "kind": "tool", + "title": "A layer of three ternary neurons", + "url": "https://t27.ai/widgets/tc-tiny-layer/", + "preview": "widgets/tc-tiny-layer/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/pathway/mlp.t27", + "source": "t27/files/specs/ml/pathway/mlp.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Fpathway%2Fmlp.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Learning XOR", + "goal": "Why one neuron cannot learn XOR, and how a hidden layer trained by backpropagation does.", + "text": "XOR is 1 when exactly one of two inputs is 1. No straight line separates the cases that give 1 from those that give 0, so a single neuron cannot learn it. A hidden layer bends the space: the spec trains a 2-8-1 network of ReLUs by backpropagation, lr 0.05, from fixed initial weights. Its loss falls from 0.8896 in epoch 1 to 1.8e-13 after 2000 epochs, and its four answers come out within 4e-7 of 0, 1, 1 and 0. The widget runs that training in your browser, from scratch for every point of the curve. The spec mlp.t27 holds the network and the test that it learns.", + "task": "Drag the epochs back to 100 and read the four answers; then find the epoch where the curve stops falling." + }, + "ru": { + "title": "Учим XOR", + "goal": "Почему один нейрон не может выучить XOR и как это делает скрытый слой, обученный обратным распространением.", + "text": "XOR равен 1, когда ровно один из двух входов равен 1. Никакая прямая не отделяет случаи, дающие 1, от дающих 0, поэтому один нейрон выучить его не может. Скрытый слой изгибает пространство: спека обучает сеть 2-8-1 из ReLU обратным распространением, lr 0.05, из фиксированных начальных весов. Её потеря падает с 0.8896 в эпохе 1 до 1.8e-13 после 2000 эпох, а четыре ответа выходят в пределах 4e-7 от 0, 1, 1 и 0. Виджет проводит это обучение в вашем браузере, заново для каждой точки кривой. Спека mlp.t27 хранит сеть и тест, что она учится.", + "task": "Отведите эпохи назад к 100 и прочитайте четыре ответа; затем найдите эпоху, где кривая перестаёт падать." + } + }, + { + "id": "lamb-and-large-batches", + "n": 21, + "module": "learning", + "widget": { + "id": "nn-lamb", + "kind": "tool", + "title": "LAMB: one learning rate for layers of every size", + "url": "https://t27.ai/widgets/nn-lamb/", + "preview": "widgets/nn-lamb/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-adam", + "kind": "tool", + "title": "Adam: the optimizer most networks are trained with", + "url": "https://t27.ai/widgets/nn-adam/", + "preview": "widgets/nn-adam/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-xor", + "kind": "tool", + "title": "XOR: a network learns what one neuron cannot", + "url": "https://t27.ai/widgets/nn-xor/", + "preview": "widgets/nn-xor/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-backprop", + "kind": "tool", + "title": "Backpropagation: how blame flows back through a layer", + "url": "https://t27.ai/widgets/nn-backprop/", + "preview": "widgets/nn-backprop/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/optimizer/lamb.t27", + "source": "t27/files/specs/ml/optimizer/lamb.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Foptimizer%2Flamb.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "LAMB and large batches", + "goal": "How LAMB scales each layer's step by its own weight norm, so one learning rate suits layers of every size.", + "text": "Training with very large batches needs a large learning rate, and one rate can be too large for a small layer and too small for a big one. LAMB takes an Adam-style update for each layer and rescales it by the trust ratio, the layer's weight norm, capped at 10, over the update's norm, so every layer moves by the same fraction of itself. In the spec, the weights (1, 2) times a scale take a step whose norm is 0.001 times theirs: 0.00447 at scale 2, and once the weight norm passes 10, near scale 4.47, the step stays at 0.01. The spec lamb.t27 computes the update for one layer and for two at once.", + "task": "Read the step at scales 1 and 2 and compare; then drag past the bend and explain why the line goes flat." + }, + "ru": { + "title": "LAMB и большие пакеты", + "goal": "Как LAMB масштабирует шаг каждого слоя его собственной нормой весов, чтобы один шаг обучения подходил слоям любого размера.", + "text": "Обучение на очень больших пакетах требует большого шага обучения, а один шаг может быть слишком большим для малого слоя и слишком малым для большого. LAMB берёт обновление в духе Adam для каждого слоя и перемасштабирует его коэффициентом доверия, нормой весов слоя, ограниченной 10, делённой на норму обновления, поэтому каждый слой сдвигается на одну и ту же долю самого себя. В спеке веса (1, 2), умноженные на масштаб, делают шаг с нормой, в 0.001 раз меньшей их собственной: 0.00447 при масштабе 2, а когда норма весов переходит 10, около масштаба 4.47, шаг остаётся на 0.01. Спека lamb.t27 вычисляет обновление для одного слоя и для двух сразу.", + "task": "Прочитайте шаг при масштабах 1 и 2 и сравните; затем перетащите за изгиб и объясните, почему линия становится плоской." + } + }, + { + "id": "a-recurrent-cell", + "n": 22, + "module": "memory-and-attention", + "widget": { + "id": "nn-rnn", + "kind": "tool", + "title": "Recurrent cells: how a network remembers a moment ago", + "url": "https://t27.ai/widgets/nn-rnn/", + "preview": "widgets/nn-rnn/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-lstm", + "kind": "tool", + "title": "LSTM gates: how a cell decides what to keep", + "url": "https://t27.ai/widgets/nn-lstm/", + "preview": "widgets/nn-lstm/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-attention", + "kind": "tool", + "title": "Attention: how a word decides which other words to read", + "url": "https://t27.ai/widgets/nn-attention/", + "preview": "widgets/nn-attention/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/recurrent/rnn_cell.t27", + "source": "t27/files/specs/ml/recurrent/rnn_cell.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Frecurrent%2Frnn_cell.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "A recurrent cell", + "goal": "How a recurrent cell carries a state from step to step, and why that memory fades.", + "text": "A sentence comes one word at a time, and a recurrent cell carries a state h from one step to the next: h' = tanh(W_x x + W_h h + b). In the spec's tiny cell W_x is 1 and W_h 0.5, so a single pulse gives 0.7616, 0.3634 and 0.1797: the memory of it roughly halves each step. A second pulse at step 3 lifts h to 0.7968, a little above where the single pulse began, because the old memory is still there. After 8 steps only 0.0466 is left. That fading is why plain cells forget long contexts. The spec rnn_cell.t27 computes each step.", + "task": "Load one pulse and read how many steps it takes to fall under 0.1; then make the input alternate." + }, + "ru": { + "title": "Рекуррентная ячейка", + "goal": "Как рекуррентная ячейка переносит состояние от шага к шагу и почему эта память затухает.", + "text": "Предложение приходит по одному слову, и рекуррентная ячейка переносит состояние h от шага к шагу: h' = tanh(W_x x + W_h h + b). В крошечной ячейке спеки W_x равен 1, а W_h 0.5, поэтому один импульс даёт 0.7616, 0.3634 и 0.1797: память о нём примерно вдвое слабеет каждый шаг. Второй импульс на шаге 3 поднимает h до 0.7968, чуть выше, чем начинался одиночный импульс, потому что старая память ещё там. После 8 шагов остаётся лишь 0.0466. Это затухание и есть причина, по которой простые ячейки забывают длинный контекст. Спека rnn_cell.t27 вычисляет каждый шаг.", + "task": "Загрузите один импульс и прочитайте, за сколько шагов он падает ниже 0.1; затем сделайте вход чередующимся." + } + }, + { + "id": "lstm-gates", + "n": 23, + "module": "memory-and-attention", + "widget": { + "id": "nn-lstm", + "kind": "tool", + "title": "LSTM gates: how a cell decides what to keep", + "url": "https://t27.ai/widgets/nn-lstm/", + "preview": "widgets/nn-lstm/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-rnn", + "kind": "tool", + "title": "Recurrent cells: how a network remembers a moment ago", + "url": "https://t27.ai/widgets/nn-rnn/", + "preview": "widgets/nn-rnn/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-attention", + "kind": "tool", + "title": "Attention: how a word decides which other words to read", + "url": "https://t27.ai/widgets/nn-attention/", + "preview": "widgets/nn-attention/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-sigmoid", + "kind": "tool", + "title": "Sigmoid: turn any number into a probability", + "url": "https://t27.ai/widgets/nn-sigmoid/", + "preview": "widgets/nn-sigmoid/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/recurrent/lstm_single.t27", + "source": "t27/files/specs/ml/recurrent/lstm_single.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Frecurrent%2Flstm_single.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "LSTM gates", + "goal": "How the forget, input and output gates of an LSTM decide what the cell keeps, writes and shows.", + "text": "An LSTM cell keeps a separate memory c and three gates, each a sigmoid between 0 and 1: forget scales the old memory, input lets in new content g, and output decides how much of the memory to show. c' = f c + i g and h' = o tanh(c'). In the spec's fixture every weight is 0, so each gate is the sigmoid of its bias: with the forget gate at 0.9975 and the input gate at 0.0025, a memory of 1 comes out as 0.9975, and the output is 0.7587. Because c passes through with only a multiply by f, its gradient survives many steps too. The spec lstm_single.t27 computes the cell.", + "task": "Load Remember and then Forget and compare the new memory; then write with the input gate open." + }, + "ru": { + "title": "Вентили LSTM", + "goal": "Как вентили забывания, входа и выхода LSTM решают, что ячейка хранит, записывает и показывает.", + "text": "Ячейка LSTM хранит отдельную память c и три вентиля, каждый это сигмоида между 0 и 1: забывание масштабирует старую память, вход впускает новое содержимое g, а выход решает, сколько памяти показать. c' = f c + i g и h' = o tanh(c'). В фикстуре спеки каждый вес равен 0, поэтому каждый вентиль это сигмоида своего смещения: при вентиле забывания 0.9975 и вентиле входа 0.0025 память 1 выходит как 0.9975, а выход равен 0.7587. Так как c проходит лишь с умножением на f, её градиент тоже переживает много шагов. Спека lstm_single.t27 вычисляет ячейку.", + "task": "Загрузите Remember, а затем Forget и сравните новую память; затем запишите с открытым вентилем входа." + } + }, + { + "id": "attention", + "n": 24, + "module": "memory-and-attention", + "widget": { + "id": "nn-attention", + "kind": "tool", + "title": "Attention: how a word decides which other words to read", + "url": "https://t27.ai/widgets/nn-attention/", + "preview": "widgets/nn-attention/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-rnn", + "kind": "tool", + "title": "Recurrent cells: how a network remembers a moment ago", + "url": "https://t27.ai/widgets/nn-rnn/", + "preview": "widgets/nn-rnn/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-lstm", + "kind": "tool", + "title": "LSTM gates: how a cell decides what to keep", + "url": "https://t27.ai/widgets/nn-lstm/", + "preview": "widgets/nn-lstm/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/recurrent/attention_mechanism.t27", + "source": "t27/files/specs/ml/recurrent/attention_mechanism.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Frecurrent%2Fattention_mechanism.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Attention", + "goal": "How attention scores every query against every key, what a softmax over each row gives, and what the causal mask removes.", + "text": "Attention lets each position decide which other positions to read. Every query is scored against every key, q . k / sqrt(d), and a softmax turns each row of scores into weights that sum to 1; the output is the values averaged by those weights. Two heads do it on the two halves of the vector. With a causal mask a position cannot read the future: in head 0, position 0 reads only itself, position 1 splits 0.452 and 0.548, and position 2 spreads 0.230, 0.321 and 0.449. Without the mask every row spreads over all three keys, from 0.21 to 0.47. The spec attention_mechanism.t27 computes every weight on its own fixture.", + "task": "Turn the mask off and on and read row 0; then compare the two heads on row 2." + }, + "ru": { + "title": "Внимание", + "goal": "Как внимание сравнивает каждый запрос с каждым ключом, что даёт softmax по каждой строке и что убирает причинная маска.", + "text": "Внимание позволяет каждой позиции решить, какие другие позиции читать. Каждый запрос сравнивается с каждым ключом, q . k / sqrt(d), и softmax превращает каждую строку оценок в веса с суммой 1; выход это значения, усреднённые этими весами. Две головы делают это на двух половинах вектора. С причинной маской позиция не может читать будущее: в голове 0 позиция 0 читает только себя, позиция 1 делит 0.452 и 0.548, а позиция 2 распределяет 0.230, 0.321 и 0.449. Без маски каждая строка распределяется по всем трём ключам, от 0.21 до 0.47. Спека attention_mechanism.t27 вычисляет каждый вес на своей фикстуре.", + "task": "Выключите и включите маску и прочитайте строку 0; затем сравните две головы в строке 2." + } + }, + { + "id": "positional-encoding", + "n": 25, + "module": "transformer-and-reward", + "widget": { + "id": "nn-positions", + "kind": "tool", + "title": "Positional encoding: how a transformer knows word order", + "url": "https://t27.ai/widgets/nn-positions/", + "preview": "widgets/nn-positions/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-attention", + "kind": "tool", + "title": "Attention: how a word decides which other words to read", + "url": "https://t27.ai/widgets/nn-attention/", + "preview": "widgets/nn-attention/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-embedding", + "kind": "tool", + "title": "Embeddings: how a word becomes a row of numbers", + "url": "https://t27.ai/widgets/nn-embedding/", + "preview": "widgets/nn-embedding/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/transformer/positional_encoding.t27", + "source": "t27/files/specs/ml/transformer/positional_encoding.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Ftransformer%2Fpositional_encoding.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "Positional encoding", + "goal": "How sines and cosines at falling frequencies give every position its own vector, and why a shift is a turn.", + "text": "Attention treats its input as a set, so the order of the words has to be added to them. The sinusoidal encoding gives each position d numbers: the sin and cos of the position times a frequency that falls by 10000^(2/d) from pair to pair. With d = 8 the four pairs turn by 1, 0.1, 0.01 and 0.001 radians per position, like the hands of four clocks: position 5 reads -0.959, 0.284 in its fast pair and 0.005, 1.000 in its slow one. Each pair has length 1, and a shift by k positions turns every pair by its own fixed angle. The spec positional_encoding.t27 computes every value.", + "task": "Step from position 0 to 1 and watch which clock moves; then jump to 37 and find the pair that still points up." + }, + "ru": { + "title": "Позиционное кодирование", + "goal": "Как синусы и косинусы убывающих частот дают каждой позиции свой вектор и почему сдвиг это поворот.", + "text": "Внимание видит свой вход как множество, поэтому порядок слов нужно к ним добавить. Синусоидальное кодирование даёт каждой позиции d чисел: sin и cos позиции, умноженной на частоту, которая от пары к паре падает в 10000^(2/d) раз. При d = 8 четыре пары поворачиваются на 1, 0.1, 0.01 и 0.001 радиана за позицию, как стрелки четырёх часов: позиция 5 читает -0.959, 0.284 в быстрой паре и 0.005, 1.000 в медленной. Длина каждой пары равна 1, и сдвиг на k позиций поворачивает каждую пару на свой постоянный угол. Спека positional_encoding.t27 вычисляет каждое значение.", + "task": "Шагните с позиции 0 на 1 и посмотрите, какие часы двигаются; затем перейдите на 37 и найдите пару, которая всё ещё смотрит вверх." + } + }, + { + "id": "an-encoder-block", + "n": 26, + "module": "transformer-and-reward", + "widget": { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-attention", + "kind": "tool", + "title": "Attention: how a word decides which other words to read", + "url": "https://t27.ai/widgets/nn-attention/", + "preview": "widgets/nn-attention/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-positions", + "kind": "tool", + "title": "Positional encoding: how a transformer knows word order", + "url": "https://t27.ai/widgets/nn-positions/", + "preview": "widgets/nn-positions/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-batchnorm", + "kind": "tool", + "title": "Batch norm: features on very different scales, made comparable", + "url": "https://t27.ai/widgets/nn-batchnorm/", + "preview": "widgets/nn-batchnorm/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/transformer/encoder_block.t27", + "source": "t27/files/specs/ml/transformer/encoder_block.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Ftransformer%2Fencoder_block.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "An encoder block", + "goal": "What one transformer encoder block does to its input, and what moving the norms in front changes.", + "text": "A transformer layer is two sublayers, each wrapped in a residual add and a layer norm: self-attention mixes the positions, then a feed-forward net of width 8 works on each position alone. In the post-norm order of the original paper the block ends with a norm, so every output row has mean 0 and variance 1.000. Pre-norm puts the norms in front of each sublayer and ends on a residual add, so its rows come out at variances 2.73, 3.33 and 0.96; deep stacks train more easily that way, with one norm added at the very top. The spec encoder_block.t27 runs one block on 3 positions, d_model 4 and 2 heads.", + "task": "Switch between post-norm and pre-norm and read the row variances; then find the position head 1 reads most." + }, + "ru": { + "title": "Блок энкодера", + "goal": "Что один блок энкодера трансформера делает со своим входом и что меняет перенос нормализаций вперёд.", + "text": "Слой трансформера это два подслоя, каждый обёрнут остаточным сложением и нормализацией слоя: самовнимание смешивает позиции, затем сеть прямого распространения ширины 8 работает с каждой позицией отдельно. В порядке post-norm из исходной статьи блок кончается нормализацией, поэтому у каждой строки выхода среднее 0 и дисперсия 1.000. Pre-norm ставит нормализации перед каждым подслоем и кончается остаточным сложением, поэтому его строки выходят с дисперсиями 2.73, 3.33 и 0.96; глубокие стопки так учатся легче, с одной нормализацией в самом верху. Спека encoder_block.t27 прогоняет один блок на 3 позициях, d_model 4 и 2 головах.", + "task": "Переключайтесь между post-norm и pre-norm и читайте дисперсии строк; затем найдите позицию, которую голова 1 читает больше всего." + } + }, + { + "id": "ppo-and-the-reward", + "n": 27, + "module": "transformer-and-reward", + "widget": { + "id": "nn-ppo", + "kind": "tool", + "title": "PPO: how an agent learns from reward without lurching", + "url": "https://t27.ai/widgets/nn-ppo/", + "preview": "widgets/nn-ppo/index.html?embed=1", + "height": 760 + }, + "also": [ + { + "id": "nn-softmax", + "kind": "tool", + "title": "Softmax: how a network turns scores into a choice", + "url": "https://t27.ai/widgets/nn-softmax/", + "preview": "widgets/nn-softmax/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-adam", + "kind": "tool", + "title": "Adam: the optimizer most networks are trained with", + "url": "https://t27.ai/widgets/nn-adam/", + "preview": "widgets/nn-adam/index.html?embed=1", + "height": 760 + }, + { + "id": "nn-encoder", + "kind": "tool", + "title": "An encoder block: what one transformer layer does", + "url": "https://t27.ai/widgets/nn-encoder/", + "preview": "widgets/nn-encoder/index.html?embed=1", + "height": 760 + } + ], + "spec": { + "path": "specs/ml/rl/ppo_clip_loss.t27", + "source": "t27/files/specs/ml/rl/ppo_clip_loss.t27", + "preview": "play/embed.html?spec=specs%2Fml%2Frl%2Fppo_clip_loss.t27&tab=term&v=7cbe9ab0c960", + "height": 480 + }, + "en": { + "title": "PPO and the reward", + "goal": "How PPO turns a reward into a policy update, and how its clip keeps one update from going too far.", + "text": "An agent learns from reward by making good actions more likely. PPO measures a change of policy by the ratio r of the new probability of an action to the old one and multiplies it by the advantage A, how much better the action did than expected. Then it clips: once r has moved more than eps the way A rewards, the objective goes flat. At r = 1.5, A = 1 and eps 0.2 the raw r A is 1.5, but PPO counts 1.2, so one batch cannot push the policy far. On the spec's batch, ratios 1, 1.1 and 0.9 with advantages 2, 1.5 and 3, the policy loss is -2.1167. The spec ppo_clip_loss.t27 computes it.", + "task": "Make the advantage negative and find where the curve goes flat now; then widen eps to 0.5." + }, + "ru": { + "title": "PPO и награда", + "goal": "Как PPO превращает награду в обновление политики и как его обрезка не даёт одному обновлению зайти слишком далеко.", + "text": "Агент учится на награде, делая хорошие действия вероятнее. PPO измеряет изменение политики отношением r новой вероятности действия к старой и умножает его на преимущество A, насколько действие превзошло ожидание. Затем он обрезает: когда r ушло больше чем на eps в ту сторону, за которую награждает A, цель становится плоской. При r = 1.5, A = 1 и eps 0.2 сырое r A равно 1.5, но PPO засчитывает 1.2, так что один пакет не может далеко сдвинуть политику. На пакете спеки, отношения 1, 1.1 и 0.9 с преимуществами 2, 1.5 и 3, потеря политики равна -2.1167. Спека ppo_clip_loss.t27 её вычисляет.", + "task": "Сделайте преимущество отрицательным и найдите, где кривая теперь становится плоской; затем расширьте eps до 0.5." + } + } + ], + "prev": { + "id": "arithmetic-and-dsp", + "route": "arithmetic-and-dsp", + "share": "learn/arithmetic-and-dsp/", + "first": "the-carry-chain", + "last": "capstone-a-filter-on-the-board", + "title": { + "en": "Arithmetic and DSP on the FPGA: from the carry chain to a filter", + "ru": "Арифметика и DSP на FPGA: от цепи переноса до фильтра" + } + }, "next": null } ] as const diff --git a/apps/website/src/lib/courseRoutes.generated.ts b/apps/website/src/lib/courseRoutes.generated.ts index ec8837b5c2..66a4753315 100644 --- a/apps/website/src/lib/courseRoutes.generated.ts +++ b/apps/website/src/lib/courseRoutes.generated.ts @@ -2,4 +2,4 @@ // Do not edit: change the .t27 source and regenerate. /** Every course's address in the app (#/, #//), in reading order. */ -export const COURSE_ROUTES = ["t27-basics","course","ai-numbers","goldenfloat","verify-hardware","clocks-and-cdc","buses-and-peripherals","ternary-computing","arithmetic-and-dsp"] as const +export const COURSE_ROUTES = ["t27-basics","course","ai-numbers","goldenfloat","verify-hardware","clocks-and-cdc","buses-and-peripherals","ternary-computing","arithmetic-and-dsp","neural-networks"] as const From 0011ae7efb2e20f5aeec6ef1d614507574582dbc Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 20:43:42 +0000 Subject: [PATCH 4/5] blog: neural networks in t27, a widget per lesson The post (EN and RU) walks through the nine modules of course 10 and the widget each lesson opens, explains how a specs/ml spec reaches the browser (t27-logic.mjs, then widget-logic.mjs), and says what the course does not show. Its figure is the XOR training loss of the 2-8-1 network and its four outputs after 2000 epochs (0.8896 to 1.8e-13), drawn by the same compiled mlp.t27 logic the nn-xor widget runs. Refs #1695 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k --- ...ral-networks-in-t27-a-widget-per-lesson.ts | 235 ++++++++++++++++++ apps/website/src/data/blog/index.ts | 31 +++ apps/website/src/data/blog/posts.ts | 2 + 3 files changed, 268 insertions(+) create mode 100644 apps/website/src/data/blog/bodies/neural-networks-in-t27-a-widget-per-lesson.ts diff --git a/apps/website/src/data/blog/bodies/neural-networks-in-t27-a-widget-per-lesson.ts b/apps/website/src/data/blog/bodies/neural-networks-in-t27-a-widget-per-lesson.ts new file mode 100644 index 0000000000..86e1ea416c --- /dev/null +++ b/apps/website/src/data/blog/bodies/neural-networks-in-t27-a-widget-per-lesson.ts @@ -0,0 +1,235 @@ +import type { Block } from '../types' + +// Course 10, neural-networks: 27 widgets, each running the fn bodies of a gHashTag/t27 specs/ml spec +// compiled to wasm (999 scripts/t27-logic.mjs, then scripts/widget-logic.mjs). The figure was drawn +// from the compiled mlp.t27 the nn-xor widget runs: xor(e, 1) every 25 epochs and xor(2000, 2..5). + +export const body: Block[] = [ + { + "kind": "p", + "text": "Course 10 of t27.ai is out: Neural networks in t27, from one neuron to a transformer block. The agents of this project think with neural networks, and the parts those networks are made of already live in gHashTag/t27 as specs with numeric tests: activations, layers, losses, optimizers, recurrent cells, attention, a transformer block. The course opens them one by one. It has 27 lessons in 9 modules, each lesson opens with a question a curious person would ask, and its widget answers it with numbers that are the spec's own fn bodies, compiled to WebAssembly and run in your browser." + }, + { + "kind": "h", + "text": "Nine modules, twenty-seven widgets" + }, + { + "kind": "table", + "head": [ + "Module", + "Widgets", + "Specs in specs/ml" + ], + "rows": [ + [ + "One neuron", + "nn-relu, nn-sigmoid, nn-tanh", + "relu_activation, sigmoid_activation, tanh_activation" + ], + [ + "New bends", + "nn-gelu, nn-silu, nn-elu", + "gelu_activation, silu_swish_activation, elu_activation" + ], + [ + "A layer", + "nn-softmax, nn-embedding, nn-dropout", + "softmax, embedding_layer, dropout_layer" + ], + [ + "Pictures", + "nn-conv, nn-maxpool, nn-batchnorm", + "avgpool2d_layer, maxpool2d_layer, batchnorm_layer" + ], + [ + "The error", + "nn-mse, nn-bce, nn-huber", + "mse_loss, binary_crossentropy_loss, huber_loss" + ], + [ + "Downhill", + "nn-sgd, nn-rmsprop, nn-adam", + "sgd, rmsprop, adam" + ], + [ + "Learning", + "nn-backprop, nn-xor, nn-lamb", + "dense_layer, mlp, lamb" + ], + [ + "Memory and attention", + "nn-rnn, nn-lstm, nn-attention", + "rnn_cell, lstm_single, attention_mechanism" + ], + [ + "The transformer and the reward", + "nn-positions, nn-encoder, nn-ppo", + "positional_encoding, encoder_block, ppo_clip_loss" + ] + ] + }, + { + "kind": "p", + "text": "The pictures are what the numbers look like: activation curves you drag along with their slopes, softmax bars that sharpen as you cool the temperature, pooling windows as heat-maps, a weight walking down a bowl under SGD, RMSProp and Adam, two heads of attention as grids, and positions as the hands of four clocks." + }, + { + "kind": "h", + "text": "A network that learns in your browser" + }, + { + "kind": "p", + "text": "Lesson 20 trains a network. mlp.t27 holds a 2-8-1 network of ReLUs and a test that it learns XOR in 2000 epochs at lr 0.05. Compiled to wasm, the same xor(epochs, which) fn runs in the widget, from scratch for every point of its loss curve. The loss falls from 0.8896 in epoch 1 to 1.8e-13, and the four answers come out within 4e-7 of 0, 1, 1 and 0. The figure below is drawn by that compiled fn." + }, + { + "kind": "figure", + "svg": "1e01e-21e-41e-61e-81e-101e-121e-140500100015002000epochsloss (log)0.88961.8e-13after 2000 epochs0 00.0000 11.0001 01.0001 10.000", + "caption": "The XOR training loss of the 2-8-1 network in mlp.t27, per epoch on a log scale, and its four outputs after 2000 epochs, computed by the compiled spec the nn-xor widget runs. The loss falls from 0.8896 to 1.8e-13 and flattens near the precision of f32 after about 600 epochs." + }, + { + "kind": "h", + "text": "How the specs got into the browser" + }, + { + "kind": "p", + "text": "No widget copies a formula. scripts/t27-logic.mjs of 999-multibots-telegraf runs t27c gen on a spec, builds the Zig with Zig 0.16 for wasm32 and writes a small module with one function per spec fn; scripts/widget-logic.mjs of the site puts it beside the widget with a byte-identical copy of the spec and stops the build when the two drift apart. The specs/ml fns take an index as usize, which t27-logic.mjs learned to lower in 999#4017; after that, 27 specs gave the 27 widgets their logic without a line rewritten. The site's spec reader learned to read an epsilon written as 1e-8 in the same change." + }, + { + "kind": "h", + "text": "What it does not show" + }, + { + "kind": "ul", + "items": [ + "Lesson 10 is average pooling over 2 x 2 windows, not a convolution: the sliding conv2d spec, t27#10612, is still open, and the lesson says so.", + "The XOR grid shows the four inputs the spec exposes, not a decision region over the plane: the spec has no fn for a point between the corners.", + "The fixtures are the specs' own small ones, 3 inputs, 4 tokens, 3 positions: nothing here was trained on real data." + ] + }, + { + "kind": "h", + "text": "Try it" + }, + { + "kind": "ul", + "items": [ + "Course: t27.ai/learn/neural-networks/", + "t27.ai/widgets/nn-softmax/, t27.ai/widgets/nn-xor/, t27.ai/widgets/nn-attention/, t27.ai/widgets/nn-positions/", + "Specs: gHashTag/t27 specs/ml/" + ] + } +] + +export const ruBody: Block[] = [ + { + "kind": "p", + "text": "На t27.ai вышел курс 10: Нейросети на t27, от одного нейрона до блока трансформера. Агенты этого проекта думают нейросетями, а части, из которых эти сети собраны, уже лежат в gHashTag/t27 спеками с числовыми тестами: функции активации, слои, функции потерь, оптимизаторы, рекуррентные ячейки, внимание, блок трансформера. Курс открывает их по одной. В нём 27 уроков в 9 модулях, каждый урок начинается с вопроса, который задал бы любопытный человек, и виджет отвечает на него числами, которые вычисляют тела fn самой спеки, скомпилированные в WebAssembly и запущенные в вашем браузере." + }, + { + "kind": "h", + "text": "Девять модулей, двадцать семь виджетов" + }, + { + "kind": "table", + "head": [ + "Модуль", + "Виджеты", + "Спеки в specs/ml" + ], + "rows": [ + [ + "Один нейрон", + "nn-relu, nn-sigmoid, nn-tanh", + "relu_activation, sigmoid_activation, tanh_activation" + ], + [ + "Новые изгибы", + "nn-gelu, nn-silu, nn-elu", + "gelu_activation, silu_swish_activation, elu_activation" + ], + [ + "Слой", + "nn-softmax, nn-embedding, nn-dropout", + "softmax, embedding_layer, dropout_layer" + ], + [ + "Картинки", + "nn-conv, nn-maxpool, nn-batchnorm", + "avgpool2d_layer, maxpool2d_layer, batchnorm_layer" + ], + [ + "Ошибка", + "nn-mse, nn-bce, nn-huber", + "mse_loss, binary_crossentropy_loss, huber_loss" + ], + [ + "Под гору", + "nn-sgd, nn-rmsprop, nn-adam", + "sgd, rmsprop, adam" + ], + [ + "Обучение", + "nn-backprop, nn-xor, nn-lamb", + "dense_layer, mlp, lamb" + ], + [ + "Память и внимание", + "nn-rnn, nn-lstm, nn-attention", + "rnn_cell, lstm_single, attention_mechanism" + ], + [ + "Трансформер и награда", + "nn-positions, nn-encoder, nn-ppo", + "positional_encoding, encoder_block, ppo_clip_loss" + ] + ] + }, + { + "kind": "p", + "text": "Картинки показывают, как выглядят числа: кривые активации, по которым можно вести курсор, вместе с наклоном, столбики softmax, которые заостряются, когда охлаждаешь температуру, окна пулинга как тепловые карты, вес, спускающийся в чашу под SGD, RMSProp и Adam, две головы внимания как сетки и позиции как стрелки четырёх часов." + }, + { + "kind": "h", + "text": "Сеть, которая учится в браузере" + }, + { + "kind": "p", + "text": "Урок 20 обучает сеть. mlp.t27 хранит сеть 2-8-1 из ReLU и тест, что она выучивает XOR за 2000 эпох при lr 0.05. Собранная в wasm, та же fn xor(epochs, which) работает в виджете, заново для каждой точки кривой потерь. Потеря падает с 0.8896 в эпохе 1 до 1.8e-13, а четыре ответа выходят в пределах 4e-7 от 0, 1, 1 и 0. Рисунок ниже нарисован этой собранной fn." + }, + { + "kind": "figure", + "svg": "1e01e-21e-41e-61e-81e-101e-121e-140500100015002000эпохипотеря (log)0.88961.8e-13после 2000 эпох0 00.0000 11.0001 01.0001 10.000", + "caption": "Потеря обучения XOR сети 2-8-1 из mlp.t27 по эпохам в логарифмической шкале и четыре её выхода после 2000 эпох, посчитанные собранной спекой, которую исполняет виджет nn-xor. Потеря падает с 0.8896 до 1.8e-13 и выполаживается около точности f32 примерно после 600 эпох." + }, + { + "kind": "h", + "text": "Как спеки попали в браузер" + }, + { + "kind": "p", + "text": "Ни один виджет не копирует формулу. scripts/t27-logic.mjs из 999-multibots-telegraf запускает t27c gen на спеке, собирает Zig через Zig 0.16 под wasm32 и пишет небольшой модуль с одной функцией на каждую fn спеки; scripts/widget-logic.mjs сайта кладёт его рядом с виджетом вместе с побайтной копией спеки и останавливает сборку, если они разошлись. Функции specs/ml принимают индекс как usize, и t27-logic.mjs научился его понижать в 999#4017; после этого 27 спек дали 27 виджетам их логику без единой переписанной строки. Читатель спек на сайте в том же изменении научился читать эпсилон, записанный как 1e-8." + }, + { + "kind": "h", + "text": "Чего это не показывает" + }, + { + "kind": "ul", + "items": [ + "Урок 10 это усредняющий пулинг по окнам 2 x 2, а не свёртка: спека скользящей conv2d, t27#10612, ещё открыта, и урок говорит об этом.", + "Сетка XOR показывает четыре входа, которые открывает спека, а не область решения на плоскости: у спеки нет fn для точки между углами.", + "Фикстуры это маленькие фикстуры самих спек, 3 входа, 4 токена, 3 позиции: ничто здесь не обучалось на настоящих данных." + ] + }, + { + "kind": "h", + "text": "Попробовать" + }, + { + "kind": "ul", + "items": [ + "Курс: t27.ai/learn/neural-networks/", + "t27.ai/widgets/nn-softmax/, t27.ai/widgets/nn-xor/, t27.ai/widgets/nn-attention/, t27.ai/widgets/nn-positions/", + "Спеки: gHashTag/t27 specs/ml/" + ] + } +] diff --git a/apps/website/src/data/blog/index.ts b/apps/website/src/data/blog/index.ts index 77f37996f0..0665822df9 100644 --- a/apps/website/src/data/blog/index.ts +++ b/apps/website/src/data/blog/index.ts @@ -2,6 +2,37 @@ import type { PostMeta } from './types' /** Индекс блога: список и метаданные без тяжёлых тел публикаций. */ export const postsIndex: PostMeta[] = [ + { + slug: "neural-networks-in-t27-a-widget-per-lesson", + title: "Neural networks in t27: 27 lessons, and a widget in each one that runs a specs/ml spec", + summary: "[every widget runs fn bodies of a gHashTag/t27 specs/ml spec compiled to wasm; lesson 10 is average pooling until t27#10612 merges; the fixtures are the specs' own, nothing is trained on real data] Course 10 opens the parts the project's agents think with: ReLU, GELU and softmax, embeddings and dropout, pooling and batch norm, MSE, cross-entropy and Huber, SGD, RMSProp, Adam and LAMB, backpropagation, a 2-8-1 network that learns XOR in the browser, a recurrent cell, LSTM gates, attention, positional encoding, an encoder block and PPO.", + date: "2026-10-18", + readingMinutes: 4, + tags: ["t27", "Course", "AI"], + receipts: [ + { label: "trinity#1695: the course issue, 27 widgets on gHashTag/t27 specs/ml", href: "https://github.com/gHashTag/trinity/issues/1695" }, + { label: "The course: Neural networks in t27", href: "https://t27.ai/learn/neural-networks/" }, + { label: "The XOR widget: a network trained in the browser", href: "https://t27.ai/widgets/nn-xor/" }, + { label: "The softmax widget", href: "https://t27.ai/widgets/nn-softmax/" }, + { label: "The attention widget", href: "https://t27.ai/widgets/nn-attention/" }, + { label: "t27#10612: the sliding conv2d spec lesson 10 waits for", href: "https://github.com/gHashTag/t27/issues/10612" }, + ], + openQuestions: [ + "Lesson 10 averages each 2 x 2 window; a convolution with a learned kernel waits for t27#10612.", + "The XOR widget shows the four inputs the spec exposes, not a decision region over the plane.", + "Every fixture is a spec's own small one; no widget runs a model trained on real data.", + ], + published: true, + ru: { + title: "Нейросети на t27: 27 уроков, и в каждом виджет, который исполняет спеку specs/ml", + summary: "[каждый виджет исполняет тела функций спеки gHashTag/t27 specs/ml, собранные в wasm; урок 10 это усредняющий пулинг, пока не слита t27#10612; фикстуры взяты из самих спек, на настоящих данных ничего не обучалось] Курс 10 открывает части, которыми думают агенты проекта: ReLU, GELU и softmax, эмбеддинги и dropout, пулинг и пакетную нормализацию, MSE, перекрёстную энтропию и функцию Хьюбера, SGD, RMSProp, Adam и LAMB, обратное распространение, сеть 2-8-1, которая учит XOR в браузере, рекуррентную ячейку, вентили LSTM, внимание, позиционное кодирование, блок энкодера и PPO.", + openQuestions: [ + "Урок 10 усредняет каждое окно 2 x 2; свёртка с выученным ядром ждёт t27#10612.", + "Виджет XOR показывает четыре входа, которые открывает спека, а не область решения на плоскости.", + "Каждая фикстура это маленькая фикстура самой спеки; ни один виджет не исполняет модель, обученную на настоящих данных.", + ], + }, + }, { slug: "a-wasm-interpreter-ran-on-the-board", title: "A WASM interpreter ran on the board: 134 of 134, from a spec", diff --git a/apps/website/src/data/blog/posts.ts b/apps/website/src/data/blog/posts.ts index f0cb43ab98..80b3fe53d0 100644 --- a/apps/website/src/data/blog/posts.ts +++ b/apps/website/src/data/blog/posts.ts @@ -1,4 +1,5 @@ import { body as body_a_wasm_interpreter_ran_on_the_board, ruBody as ruBody_a_wasm_interpreter_ran_on_the_board } from './bodies/a-wasm-interpreter-ran-on-the-board' +import { body as body_neural_networks_in_t27_a_widget_per_lesson, ruBody as ruBody_neural_networks_in_t27_a_widget_per_lesson } from './bodies/neural-networks-in-t27-a-widget-per-lesson' import { body as body_arithmetic_and_dsp_a_widget_per_lesson, ruBody as ruBody_arithmetic_and_dsp_a_widget_per_lesson } from './bodies/arithmetic-and-dsp-a-widget-per-lesson' import { body as body_the_ternary_machine_course, ruBody as ruBody_the_ternary_machine_course } from './bodies/the-ternary-machine-course' import { body as body_three_widgets_under_the_bus, ruBody as ruBody_three_widgets_under_the_bus } from './bodies/three-widgets-under-the-bus' @@ -140,6 +141,7 @@ const bodies: Record = { 'bypass-or-a-broken-shift': { body: body_bypass_or_a_broken_shift, ruBody: ruBody_bypass_or_a_broken_shift }, 'the-ternary-machine-course': { body: body_the_ternary_machine_course, ruBody: ruBody_the_ternary_machine_course }, 'three-widgets-under-the-bus': { body: body_three_widgets_under_the_bus, ruBody: ruBody_three_widgets_under_the_bus }, + 'neural-networks-in-t27-a-widget-per-lesson': { body: body_neural_networks_in_t27_a_widget_per_lesson, ruBody: ruBody_neural_networks_in_t27_a_widget_per_lesson }, 'arithmetic-and-dsp-a-widget-per-lesson': { body: body_arithmetic_and_dsp_a_widget_per_lesson, ruBody: ruBody_arithmetic_and_dsp_a_widget_per_lesson }, 'the-back-half-of-openxc7-from-a-spec': { body: body_the_back_half_of_openxc7_from_a_spec, ruBody: ruBody_the_back_half_of_openxc7_from_a_spec }, 'tri-mined-not-sold': { body: body_tri_mined_not_sold, ruBody: ruBody_tri_mined_not_sold }, From 3e0833d6f609bc9e83310985ee9c48ba0b34a1d2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 21:36:34 +0000 Subject: [PATCH 5/5] widgets(nn-maxpool): the output side comes from the spec's out_side The widget held the output sides as K_OUT_SIDES = [2, 2, 3, 1], which are results of the spec fn out_size. A widget-spec test re-derived out_size's formula by hand to hold them. Both broke the mirror law (review 5565039954). - Vendor specs/ml/layers/maxpool2d_layer.t27 from t27 master 2e53089d5, byte-identical, into public/t27/files and nn-maxpool/logic.t27. That commit (gHashTag/t27#10665) added the lowerable fn out_side(kernel, stride). - Lower it again with t27-logic.mjs and import it with widget-logic.mjs. logic.js now exports outSide. - tool.js gets the output grid's shape and the "output n x n" tile from outSide(k, st). - Drop K_OUT_SIDES and the test every_output_side_follows_from_kernel_and_stride. A new test, the_four_configs_are_the_spec_window_stride_pairs, holds the K_KERNELS/K_STRIDES inputs. - The course spec says the max-pool spec is vendored from 2e53089d5. Widget pages and both max-pooling lesson pages are regenerated. Course 10, gHashTag/trinity#1695. Spec: gHashTag/t27#10665. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k --- .../public/learn/max-pooling/index.html | 22 ++++++++++++++++++ apps/website/public/learn/neural-networks.t27 | 3 ++- .../public/ru/learn/max-pooling/index.html | 22 ++++++++++++++++++ .../files/specs/ml/layers/maxpool2d_layer.t27 | 22 ++++++++++++++++++ .../public/widgets/nn-maxpool/index.html | 12 +++++----- .../public/widgets/nn-maxpool/logic.js | 8 +++++-- .../public/widgets/nn-maxpool/logic.t27 | 22 ++++++++++++++++++ .../public/widgets/nn-maxpool/nn-maxpool.t27 | 23 +++++++++++-------- .../website/public/widgets/nn-maxpool/tool.js | 13 ++++++----- apps/website/specs/course/neural-networks.t27 | 3 ++- apps/website/specs/widgets/nn-maxpool.t27 | 23 +++++++++++-------- apps/website/src/lib/course.generated.ts | 4 ++-- 12 files changed, 139 insertions(+), 38 deletions(-) diff --git a/apps/website/public/learn/max-pooling/index.html b/apps/website/public/learn/max-pooling/index.html index 714ae245ba..10a63d9853 100644 --- a/apps/website/public/learn/max-pooling/index.html +++ b/apps/website/public/learn/max-pooling/index.html @@ -149,6 +149,13 @@

Max pooling

return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; } + // The output side on the 4 x 4 fixture for a k x k window and a stride. + // out_size takes a MaxPool2DConfig struct and does not lower to WASM; this + // takes two integers, so a host reads the side from the compiled spec. + fn out_side(kernel: u32, stride: u32) -> u32 { + return out_size(4, cfg(kernel, stride)); + } + // The 4 x 4 fixture // 1 2 5 6 // 3 4 8 7 @@ -210,6 +217,21 @@

Max pooling

when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + // The four window/stride pairs the nn-maxpool widget offers, on the 4 x 4 fixture: + // 2 x 2 stride 2 -> 2, 3 x 3 stride 1 -> 2, 2 x 2 stride 1 -> 3, 4 x 4 stride 1 -> 1 + test out_side_of_each_widget_config + given halved = out_side(2, 2) + when whole = out_side(4, 1) + then halved == 2 and out_side(3, 1) == 2 and out_side(2, 1) == 3 and whole == 1 + + // Edges: a 1 x 1 window at stride 1 keeps the side; a stride that does not + // divide (4 - k) rounds down (3 x 3 at stride 2 fits one window, 1 x 1 at + // stride 3 fits two) + test out_side_identity_and_floor + given same = out_side(1, 1) + when floored = out_side(3, 2) + then same == 4 and floored == 1 and out_side(1, 3) == 2 + invariant maxpool_output_size_formula assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2

Open the lesson's spec in the player ↗

diff --git a/apps/website/public/learn/neural-networks.t27 b/apps/website/public/learn/neural-networks.t27 index 7d365b8726..1d004ddf19 100644 --- a/apps/website/public/learn/neural-networks.t27 +++ b/apps/website/public/learn/neural-networks.t27 @@ -13,7 +13,8 @@ ; agents of this project think with neural networks; this course opens their parts as the ; gHashTag/t27 specs/ml specs they are written in, each with numeric tests. Every widget runs the ; fn bodies of one of those specs compiled to WebAssembly (public/widgets//logic.js, held to -; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059. +; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059; the +; max-pool spec from 2e53089d5, which added out_side (gHashTag/t27#10665) for the nn-maxpool widget. ; WHAT THE COURSE DOES NOT DO: it says no number of its own. Every number in a lesson is one the ; lesson spec computes and its widget shows. Lesson 10 is average pooling, not a convolution: the diff --git a/apps/website/public/ru/learn/max-pooling/index.html b/apps/website/public/ru/learn/max-pooling/index.html index 067218c038..44932debca 100644 --- a/apps/website/public/ru/learn/max-pooling/index.html +++ b/apps/website/public/ru/learn/max-pooling/index.html @@ -149,6 +149,13 @@

Max pooling: максимум окна

return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; } + // The output side on the 4 x 4 fixture for a k x k window and a stride. + // out_size takes a MaxPool2DConfig struct and does not lower to WASM; this + // takes two integers, so a host reads the side from the compiled spec. + fn out_side(kernel: u32, stride: u32) -> u32 { + return out_size(4, cfg(kernel, stride)); + } + // The 4 x 4 fixture // 1 2 5 6 // 3 4 8 7 @@ -210,6 +217,21 @@

Max pooling: максимум окна

when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + // The four window/stride pairs the nn-maxpool widget offers, on the 4 x 4 fixture: + // 2 x 2 stride 2 -> 2, 3 x 3 stride 1 -> 2, 2 x 2 stride 1 -> 3, 4 x 4 stride 1 -> 1 + test out_side_of_each_widget_config + given halved = out_side(2, 2) + when whole = out_side(4, 1) + then halved == 2 and out_side(3, 1) == 2 and out_side(2, 1) == 3 and whole == 1 + + // Edges: a 1 x 1 window at stride 1 keeps the side; a stride that does not + // divide (4 - k) rounds down (3 x 3 at stride 2 fits one window, 1 x 1 at + // stride 3 fits two) + test out_side_identity_and_floor + given same = out_side(1, 1) + when floored = out_side(3, 2) + then same == 4 and floored == 1 and out_side(1, 3) == 2 + invariant maxpool_output_size_formula assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2

Открыть спеку урока в плеере ↗

diff --git a/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 b/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 index 6841238ca8..7b972a41a5 100644 --- a/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 +++ b/apps/website/public/t27/files/specs/ml/layers/maxpool2d_layer.t27 @@ -82,6 +82,13 @@ module Maxpool2d; return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; } + // The output side on the 4 x 4 fixture for a k x k window and a stride. + // out_size takes a MaxPool2DConfig struct and does not lower to WASM; this + // takes two integers, so a host reads the side from the compiled spec. + fn out_side(kernel: u32, stride: u32) -> u32 { + return out_size(4, cfg(kernel, stride)); + } + // The 4 x 4 fixture // 1 2 5 6 // 3 4 8 7 @@ -143,5 +150,20 @@ module Maxpool2d; when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + // The four window/stride pairs the nn-maxpool widget offers, on the 4 x 4 fixture: + // 2 x 2 stride 2 -> 2, 3 x 3 stride 1 -> 2, 2 x 2 stride 1 -> 3, 4 x 4 stride 1 -> 1 + test out_side_of_each_widget_config + given halved = out_side(2, 2) + when whole = out_side(4, 1) + then halved == 2 and out_side(3, 1) == 2 and out_side(2, 1) == 3 and whole == 1 + + // Edges: a 1 x 1 window at stride 1 keeps the side; a stride that does not + // divide (4 - k) rounds down (3 x 3 at stride 2 fits one window, 1 x 1 at + // stride 3 fits two) + test out_side_identity_and_floor + given same = out_side(1, 1) + when floored = out_side(3, 2) + then same == 4 and floored == 1 and out_side(1, 3) == 2 + invariant maxpool_output_size_formula assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2 diff --git a/apps/website/public/widgets/nn-maxpool/index.html b/apps/website/public/widgets/nn-maxpool/index.html index 2048f4cdda..7583979a4e 100644 --- a/apps/website/public/widgets/nn-maxpool/index.html +++ b/apps/website/public/widgets/nn-maxpool/index.html @@ -1,5 +1,5 @@ - + @@ -24,8 +24,8 @@ - - + + @@ -38,10 +38,10 @@

Max pooling: what a network keeps when it shrinks a picture

This page sets no cookie and sends nothing anywhere.

-
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget
+
Where the numbers come from
  • gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 2e53089d5): every value on the page is its fn bodies, compiled to wasm (logic.js)
  • Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget

This widget's .t27 source · All widgets

- - + + diff --git a/apps/website/public/widgets/nn-maxpool/logic.js b/apps/website/public/widgets/nn-maxpool/logic.js index 62c5f07970..be364622d8 100644 --- a/apps/website/public/widgets/nn-maxpool/logic.js +++ b/apps/website/public/widgets/nn-maxpool/logic.js @@ -3,9 +3,9 @@ // The spec's own fn bodies, compiled: t27c gen (Zig) -> zig 0.16.0 (wasm32). // Change the spec in gHashTag/t27, vendor it, regenerate. A rule written // by hand beside this file is the thing this file exists to end. -// spec-sha256: 70e420bb07469fa920c9fabeaaa29116ee913b5b203951594cfb7ef20730db46 +// spec-sha256: 12627dff26da63deb67347730d28228fda9b60ca09779e37d052f4a94f3e7e0a // Imported by scripts/widget-logic.mjs for public/widgets/nn-maxpool/: types stripped, nothing else changed. -const WASM = "AGFzbQEAAAABFANgAX8BfWADf39/AGAEf39/fwF9AwQDAAECBAUBcAEBAQUDAQARBgkBfwFBgIDAAAsHKgMGbWVtb3J5AgAPdDI3X2JhY2t3YXJkX2F0AAALdDI3X3Bvb2xfYXQAAgqOBgONAgIDfwF9I4CAgIAAQYABayIBJICAgIAAIAFBIGpCADcDACABQgA3AxggAUKAgICAEDcCNCABQoKAgIAgNwIsIAFBAToAPCABQQE6AEAgAUEsaiABQQhqIAFBGGoQgYCAgAACQEHAAEUNACABQcAAakHAgMCAAEHAAPwKAAALQQAhAgN9AkAgAkHAAEcNAEEAIQICQANAIAJBEEYNASABQcAAaiABQRhqIAJqKAIAQQJ0aiIDIAMqAgAgAkGAgcCAAGoqAgCSOAIAIAJBBGohAgwACwsgAUHAAGogAEECdGoqAgAhBCABQYABaiSAgICAACAEDwsgAUHAAGogAmpBADYCACACQQRqIQIMAAsLygIBFH8gACgCBCIDQQR0IQQgA0ECdCEFQQQgACgCACIGayADbiIHQQFqIQhBACEJQYCAwIAAIQpBACELAkADQCALIAdLDQEgCyAIbCEMIAsgBWwhDUEAIQ4gCiEPIAkhEANAAkACQCAOIAdLDQAgDiADbCANaiERQQAhEiAPIRMgECEUA0AgEiAGRg0CIBMhFSAUIRYgBiEAAkADQCAARQ0BIBYgESAVKgIAIBFBAnRBgIDAgABqKgIAXhshESAVQQRqIRUgFkEBaiEWIABBf2ohAAwACwsgE0EQaiETIBRBBGohFCASQQFqIRIMAAsLIAogBGohCiAJIAVqIQkgC0EBaiELDAILIAEgDiAMakECdCIAaiARQQJ0QYCAwIAAaioCADgCACACIABqIBE2AgAgDyAFaiEPIBAgA2ohECAOQQFqIQ4MAAsLCwuwAQICfwF9I4CAgIAAQeAAayIEJICAgIAAAkBBJEUiBQ0AIARBAEEk/AsACwJAIAUNACAEQSRqQQBBJPwLAAsgBEKAgICAEDcCUCAEIAE2AkwgBCAANgJIIARBAToAWCAEQQE6AFwgBEHIAGogBCAEQSRqEIGAgIAAAkACQCACDQAgBCADQQJ0aioCACEGDAELIARBJGogA0ECdGooAgCzIQYLIARB4ABqJICAgIAAIAYLC5oBAQBBgIDAAAuQAQAAgD8AAABAAACgQAAAwEAAAEBAAACAQAAAAEEAAOBAAAAAAAAAgL8AAEDAAAAAwAAAgMAAABBBAADAwAAAoMAAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAACAPwAAAEAAAEBAAACAQA=="; +const WASM = "AGFzbQEAAAABGgRgAX8BfWADf39/AGAEf39/fwF9YAJ/fwF/AwUEAAECAwQFAXABAQEFAwEAEQYJAX8BQYCAwAALBzkEBm1lbW9yeQIAD3QyN19iYWNrd2FyZF9hdAAAC3QyN19wb29sX2F0AAIMdDI3X291dF9zaWRlAAMKnAYEjQICA38BfSOAgICAAEGAAWsiASSAgICAACABQSBqQgA3AwAgAUIANwMYIAFCgICAgBA3AjQgAUKCgICAIDcCLCABQQE6ADwgAUEBOgBAIAFBLGogAUEIaiABQRhqEIGAgIAAAkBBwABFDQAgAUHAAGpBwIDAgABBwAD8CgAAC0EAIQIDfQJAIAJBwABHDQBBACECAkADQCACQRBGDQEgAUHAAGogAUEYaiACaigCAEECdGoiAyADKgIAIAJBgIHAgABqKgIAkjgCACACQQRqIQIMAAsLIAFBwABqIABBAnRqKgIAIQQgAUGAAWokgICAgAAgBA8LIAFBwABqIAJqQQA2AgAgAkEEaiECDAALC8oCARR/IAAoAgQiA0EEdCEEIANBAnQhBUEEIAAoAgAiBmsgA24iB0EBaiEIQQAhCUGAgMCAACEKQQAhCwJAA0AgCyAHSw0BIAsgCGwhDCALIAVsIQ1BACEOIAohDyAJIRADQAJAAkAgDiAHSw0AIA4gA2wgDWohEUEAIRIgDyETIBAhFANAIBIgBkYNAiATIRUgFCEWIAYhAAJAA0AgAEUNASAWIBEgFSoCACARQQJ0QYCAwIAAaioCAF4bIREgFUEEaiEVIBZBAWohFiAAQX9qIQAMAAsLIBNBEGohEyAUQQRqIRQgEkEBaiESDAALCyAKIARqIQogCSAFaiEJIAtBAWohCwwCCyABIA4gDGpBAnQiAGogEUECdEGAgMCAAGoqAgA4AgAgAiAAaiARNgIAIA8gBWohDyAQIANqIRAgDkEBaiEODAALCwsLsAECAn8BfSOAgICAAEHgAGsiBCSAgICAAAJAQSRFIgUNACAEQQBBJPwLAAsCQCAFDQAgBEEkakEAQST8CwALIARCgICAgBA3AlAgBCABNgJMIAQgADYCSCAEQQE6AFggBEEBOgBcIARByABqIAQgBEEkahCBgICAAAJAAkAgAg0AIAQgA0ECdGoqAgAhBgwBCyAEQSRqIANBAnRqKAIAsyEGCyAEQeAAaiSAgICAACAGCw0AQQQgAGsgAW5BAWoLC5oBAQBBgIDAAAuQAQAAgD8AAABAAACgQAAAwEAAAEBAAACAQAAAAEEAAOBAAAAAAAAAgL8AAEDAAAAAwAAAgMAAABBBAADAwAAAoMAAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAAAQQQAAEEEAABBBAACAPwAAAEAAAEBAAACAQA=="; const W = new WebAssembly.Instance( new WebAssembly.Module(Uint8Array.from(atob(WASM), (c) => c.charCodeAt(0))) ).exports; @@ -14,6 +14,9 @@ function int(v, lo, hi, at) { throw new RangeError(`${at}: ${v} is outside ${lo}..${hi}`); return v; } +function outSide(kernel, stride) { + return W.t27_out_side(int(kernel, 0, 4294967295, "out_side.kernel"), int(stride, 0, 4294967295, "out_side.stride")) >>> 0; +} function poolAt(kernel, stride, which, index) { return W.t27_pool_at(int(kernel, 0, 4294967295, "pool_at.kernel"), int(stride, 0, 4294967295, "pool_at.stride"), int(which, 0, 255, "pool_at.which"), int(index, 0, 4294967295, "pool_at.index")); } @@ -24,5 +27,6 @@ const __NOT_LOWERED__ = Object.freeze(["out_size", "forward", "backward", "cfg"] export { __NOT_LOWERED__, backwardAt, + outSide, poolAt }; diff --git a/apps/website/public/widgets/nn-maxpool/logic.t27 b/apps/website/public/widgets/nn-maxpool/logic.t27 index 6841238ca8..7b972a41a5 100644 --- a/apps/website/public/widgets/nn-maxpool/logic.t27 +++ b/apps/website/public/widgets/nn-maxpool/logic.t27 @@ -82,6 +82,13 @@ module Maxpool2d; return MaxPool2DConfig{ .kernel_size = kernel, .stride = stride, .padding = 0, .dilation = 1, .return_indices = true }; } + // The output side on the 4 x 4 fixture for a k x k window and a stride. + // out_size takes a MaxPool2DConfig struct and does not lower to WASM; this + // takes two integers, so a host reads the side from the compiled spec. + fn out_side(kernel: u32, stride: u32) -> u32 { + return out_size(4, cfg(kernel, stride)); + } + // The 4 x 4 fixture // 1 2 5 6 // 3 4 8 7 @@ -143,5 +150,20 @@ module Maxpool2d; when others = backward_at(0) + backward_at(1) + backward_at(4) + backward_at(15) then total == 10.0 and others == 0.0 and backward_at(13) == 3.0 + // The four window/stride pairs the nn-maxpool widget offers, on the 4 x 4 fixture: + // 2 x 2 stride 2 -> 2, 3 x 3 stride 1 -> 2, 2 x 2 stride 1 -> 3, 4 x 4 stride 1 -> 1 + test out_side_of_each_widget_config + given halved = out_side(2, 2) + when whole = out_side(4, 1) + then halved == 2 and out_side(3, 1) == 2 and out_side(2, 1) == 3 and whole == 1 + + // Edges: a 1 x 1 window at stride 1 keeps the side; a stride that does not + // divide (4 - k) rounds down (3 x 3 at stride 2 fits one window, 1 x 1 at + // stride 3 fits two) + test out_side_identity_and_floor + given same = out_side(1, 1) + when floored = out_side(3, 2) + then same == 4 and floored == 1 and out_side(1, 3) == 2 + invariant maxpool_output_size_formula assert out_size(4, cfg(2, 2)) == 2 and out_size(4, cfg(3, 1)) == 2 and out_size(5, cfg(2, 2)) == 2 diff --git a/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 b/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 index f26b20b6c6..0cfa3a452c 100644 --- a/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 +++ b/apps/website/public/widgets/nn-maxpool/nn-maxpool.t27 @@ -9,8 +9,9 @@ ; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. ; WHAT IT DOES: the reader picks one of four window and stride pairs and taps an output. Outputs and -; argmax indices are pool_at(kernel, stride, 0 or 1, i); for 2 x 2 stride 2 the gradient view is -; backward_at(i), the spec's output gradients 1, 2, 3, 4. +; argmax indices are pool_at(kernel, stride, 0 or 1, i) and the output side is out_side(kernel, +; stride); for 2 x 2 stride 2 the gradient view is backward_at(i), the spec's output gradients +; 1, 2, 3, 4. ; WHAT IT DOES NOT CLAIM: the grid is the spec's fixture, repeated as K_INPUT; the outputs and ; argmax come from the compiled fn, so a K_INPUT that drifted would show a max that is not in its @@ -26,7 +27,7 @@ pub const DESCRIPTION : str = "Pick a window size and stride and tap an output: pub const IMAGE_ALT : str = "Max-pool card, 2 x 2 windows with stride 2: the spec's 4 x 4 grid in pink and green, with cell 13 (value 9) outlined inside its window; the 2 x 2 output reads 4, 8, 9, -2 with 9 outlined. Tiles read max 9, argmax 13, output 2 x 2 and gradient at the max 3."; pub const HOOK : str = "On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2; their gradients land on cells 5, 6, 13 and 11 and nowhere else."; pub const CATEGORY : str = "compiler"; -pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 2e53089d5): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; pub const READS_LOCAL_FILES : bool = false; pub const SENDS_NOTHING : bool = true; @@ -38,7 +39,6 @@ pub const K_SIDE : u8 = 4; pub const K_INPUT : [16]i8 = [1, 2, 5, 6, 3, 4, 8, 7, 0, -1, -3, -2, -4, 9, -6, -5]; pub const K_KERNELS : [4]u8 = [2, 3, 2, 4]; pub const K_STRIDES : [4]u8 = [2, 1, 1, 1]; -pub const K_OUT_SIDES : [4]u8 = [2, 2, 3, 1]; pub const K_PRESET_CFG : [3]u8 = [0, 1, 2]; pub const K_PRESET_CELL : [3]u8 = [2, 0, 4]; pub const K_PRESET_GRAD : [3]u8 = [0, 0, 0]; @@ -68,11 +68,15 @@ test the_card_is_the_share_size { assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; } -test every_output_side_follows_from_kernel_and_stride { - assert K_OUT_SIDES[0] * K_STRIDES[0] + K_KERNELS[0] - K_STRIDES[0] == K_SIDE; - assert K_OUT_SIDES[1] * K_STRIDES[1] + K_KERNELS[1] - K_STRIDES[1] == K_SIDE; - assert K_OUT_SIDES[2] * K_STRIDES[2] + K_KERNELS[2] - K_STRIDES[2] == K_SIDE; - assert K_OUT_SIDES[3] * K_STRIDES[3] + K_KERNELS[3] - K_STRIDES[3] == K_SIDE; +test the_four_configs_are_the_spec_window_stride_pairs { + assert K_KERNELS[0] == 2; + assert K_STRIDES[0] == 2; + assert K_KERNELS[1] == 3; + assert K_STRIDES[1] == 1; + assert K_KERNELS[2] == 2; + assert K_STRIDES[2] == 1; + assert K_KERNELS[3] == K_SIDE; + assert K_STRIDES[3] == 1; } test the_grid_is_the_spec_fixture { @@ -80,5 +84,4 @@ test the_grid_is_the_spec_fixture { assert K_INPUT[6] == 8; assert K_INPUT[13] == 9; assert K_INPUT[11] + 2 == 0; - assert K_OUT_SIDES[2] * K_OUT_SIDES[2] <= 9; } diff --git a/apps/website/public/widgets/nn-maxpool/tool.js b/apps/website/public/widgets/nn-maxpool/tool.js index 7828965276..ee50f11cbb 100644 --- a/apps/website/public/widgets/nn-maxpool/tool.js +++ b/apps/website/public/widgets/nn-maxpool/tool.js @@ -1,15 +1,16 @@ // nn-maxpool/tool.js -- lesson 11 of neural-networks: what a network keeps when it shrinks a // picture. Max pooling keeps the largest value of each window and remembers where it was; learning -// then sends each window's gradient to that one cell. Every output and argmax is pool_at, every -// gradient backward_at of gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27, compiled to wasm -// (./logic.js), on the spec's 4 x 4 fixture (K_INPUT, held equal to it by the tests below the spec). +// then sends each window's gradient to that one cell. Every output and argmax is pool_at, the +// output side out_side, every gradient backward_at of gHashTag/t27 +// specs/ml/layers/maxpool2d_layer.t27, compiled to wasm (./logic.js), on the spec's 4 x 4 fixture +// (K_INPUT, held equal to it by the tests below the spec). // Words are SAY_ and numbers K_ constants of specs/widgets/nn-maxpool.t27. -import { backwardAt, poolAt } from './logic.js' +import { backwardAt, outSide, poolAt } from './logic.js' import { COLORS, K, W, ask, canvas, controls, el, fmt, heat, root, say, source, tiles, tone } from '../nn-kit.js' const SIDE = K('K_SIDE', 4) const INPUT = K('K_INPUT', []) -const KS = K('K_KERNELS', []), ST = K('K_STRIDES', []), OUT = K('K_OUT_SIDES', []) +const KS = K('K_KERNELS', []), ST = K('K_STRIDES', []) const ctl = controls([ { key: 'cfg', label: say('SAY_CONFIG'), kind: 'choice', options: W.SAY_CONFIG_NAMES ?? [] }, { key: 'cell', kind: 'hidden', min: 0, max: 8 }, @@ -23,7 +24,7 @@ const inLabel = el('p', { class: 'dk-label' }) root.replaceChildren(ask(say('SAY_ASK')), ctl.node, el('div', { class: 'nn-two' }, el('div', {}, inLabel, img), el('div', {}, el('p', { class: 'dk-label' }, say('SAY_OUT_LABEL')), out)), stat, el('p', { class: 'dk-note' }, say('SAY_NOTE')), source()) function draw(s) { - const k = KS[s.cfg], st = ST[s.cfg], n = OUT[s.cfg] + const k = KS[s.cfg], st = ST[s.cfg], n = outSide(k, st) const cell = Math.min(s.cell, n * n - 1) const oy = Math.floor(cell / n), ox = cell % n const inWin = (r, c) => r >= oy * st && r < oy * st + k && c >= ox * st && c < ox * st + k diff --git a/apps/website/specs/course/neural-networks.t27 b/apps/website/specs/course/neural-networks.t27 index 7d365b8726..1d004ddf19 100644 --- a/apps/website/specs/course/neural-networks.t27 +++ b/apps/website/specs/course/neural-networks.t27 @@ -13,7 +13,8 @@ ; agents of this project think with neural networks; this course opens their parts as the ; gHashTag/t27 specs/ml specs they are written in, each with numeric tests. Every widget runs the ; fn bodies of one of those specs compiled to WebAssembly (public/widgets//logic.js, held to -; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059. +; its spec by scripts/widget-logic.mjs), vendored byte for byte from t27 master 239b4b059; the +; max-pool spec from 2e53089d5, which added out_side (gHashTag/t27#10665) for the nn-maxpool widget. ; WHAT THE COURSE DOES NOT DO: it says no number of its own. Every number in a lesson is one the ; lesson spec computes and its widget shows. Lesson 10 is average pooling, not a convolution: the diff --git a/apps/website/specs/widgets/nn-maxpool.t27 b/apps/website/specs/widgets/nn-maxpool.t27 index f26b20b6c6..0cfa3a452c 100644 --- a/apps/website/specs/widgets/nn-maxpool.t27 +++ b/apps/website/specs/widgets/nn-maxpool.t27 @@ -9,8 +9,9 @@ ; Numbers are integers (the schema reads no float): a K_ name ending in _C is in hundredths. ; WHAT IT DOES: the reader picks one of four window and stride pairs and taps an output. Outputs and -; argmax indices are pool_at(kernel, stride, 0 or 1, i); for 2 x 2 stride 2 the gradient view is -; backward_at(i), the spec's output gradients 1, 2, 3, 4. +; argmax indices are pool_at(kernel, stride, 0 or 1, i) and the output side is out_side(kernel, +; stride); for 2 x 2 stride 2 the gradient view is backward_at(i), the spec's output gradients +; 1, 2, 3, 4. ; WHAT IT DOES NOT CLAIM: the grid is the spec's fixture, repeated as K_INPUT; the outputs and ; argmax come from the compiled fn, so a K_INPUT that drifted would show a max that is not in its @@ -26,7 +27,7 @@ pub const DESCRIPTION : str = "Pick a window size and stride and tap an output: pub const IMAGE_ALT : str = "Max-pool card, 2 x 2 windows with stride 2: the spec's 4 x 4 grid in pink and green, with cell 13 (value 9) outlined inside its window; the 2 x 2 output reads 4, 8, 9, -2 with 9 outlined. Tiles read max 9, argmax 13, output 2 x 2 and gradient at the max 3."; pub const HOOK : str = "On the spec's 4 x 4 grid, 2 x 2 windows with stride 2 keep 4, 8, 9 and -2; their gradients land on cells 5, 6, 13 and 11 and nowhere else."; pub const CATEGORY : str = "compiler"; -pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 239b4b059): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; +pub const DATA_SOURCES : [2]str = ["gHashTag/t27 specs/ml/layers/maxpool2d_layer.t27 (t27 master 2e53089d5): every value on the page is its fn bodies, compiled to wasm (logic.js)", "Course 10 of t27.ai, neural-networks (gHashTag/trinity#1695): lesson 11 opens this widget"]; pub const READS_LOCAL_FILES : bool = false; pub const SENDS_NOTHING : bool = true; @@ -38,7 +39,6 @@ pub const K_SIDE : u8 = 4; pub const K_INPUT : [16]i8 = [1, 2, 5, 6, 3, 4, 8, 7, 0, -1, -3, -2, -4, 9, -6, -5]; pub const K_KERNELS : [4]u8 = [2, 3, 2, 4]; pub const K_STRIDES : [4]u8 = [2, 1, 1, 1]; -pub const K_OUT_SIDES : [4]u8 = [2, 2, 3, 1]; pub const K_PRESET_CFG : [3]u8 = [0, 1, 2]; pub const K_PRESET_CELL : [3]u8 = [2, 0, 4]; pub const K_PRESET_GRAD : [3]u8 = [0, 0, 0]; @@ -68,11 +68,15 @@ test the_card_is_the_share_size { assert K_CARD_WIDTH * 21 == K_CARD_HEIGHT * 40; } -test every_output_side_follows_from_kernel_and_stride { - assert K_OUT_SIDES[0] * K_STRIDES[0] + K_KERNELS[0] - K_STRIDES[0] == K_SIDE; - assert K_OUT_SIDES[1] * K_STRIDES[1] + K_KERNELS[1] - K_STRIDES[1] == K_SIDE; - assert K_OUT_SIDES[2] * K_STRIDES[2] + K_KERNELS[2] - K_STRIDES[2] == K_SIDE; - assert K_OUT_SIDES[3] * K_STRIDES[3] + K_KERNELS[3] - K_STRIDES[3] == K_SIDE; +test the_four_configs_are_the_spec_window_stride_pairs { + assert K_KERNELS[0] == 2; + assert K_STRIDES[0] == 2; + assert K_KERNELS[1] == 3; + assert K_STRIDES[1] == 1; + assert K_KERNELS[2] == 2; + assert K_STRIDES[2] == 1; + assert K_KERNELS[3] == K_SIDE; + assert K_STRIDES[3] == 1; } test the_grid_is_the_spec_fixture { @@ -80,5 +84,4 @@ test the_grid_is_the_spec_fixture { assert K_INPUT[6] == 8; assert K_INPUT[13] == 9; assert K_INPUT[11] + 2 == 0; - assert K_OUT_SIDES[2] * K_OUT_SIDES[2] <= 9; } diff --git a/apps/website/src/lib/course.generated.ts b/apps/website/src/lib/course.generated.ts index 64a355dea6..858a1c0ec0 100644 --- a/apps/website/src/lib/course.generated.ts +++ b/apps/website/src/lib/course.generated.ts @@ -1,5 +1,5 @@ // GENERATED by scripts/course-from-spec.mjs from specs/course/courses.t27, specs/course/t27-basics.t27, specs/course/course.t27, specs/course/ai-numbers.t27, specs/course/goldenfloat.t27, specs/course/verify-hardware.t27, specs/course/clocks-and-cdc.t27, specs/course/buses-and-peripherals.t27, specs/course/ternary-computing.t27, specs/course/arithmetic-and-dsp.t27, specs/course/neural-networks.t27 and their Russian bundles -// spec sha256 t27-basics 4827f6b9f5d95ae98e1d49f037966d2cc826e07c691044f2f5fa1ee9c98ae474, course 8429472829c5d9a0782b2d2b21ff26879a429c5470f4abb5088f1e1a7fa674be, ai-numbers 7f736e357ef13446dfa8f978482cc28c7710caac3f7396769a8fc01b91e20802, goldenfloat d6b6019b8e6bf77a41991b32a3a3d1b5eb78ca4b7078e2bf5f5436df3dd7c59c, verify-hardware 7ca437575eaa8f8646f42c82b75862f091fb509708de152c4e18ed76ee39d4cf, clocks-and-cdc 7d491967f9326fcde194ab19a9bfa7f0ed960ba94d7ca3d82df0747e269c5acc, buses-and-peripherals 4dfdbd8c909d7ad8f1ac2d4f7025c77f0619ade92b181212ea9b589262695acc, ternary-computing e0a14010163f00208d5b54c800e6ce3f05e6b8581de94c0323097b00b1854437, arithmetic-and-dsp c2b6bfd642e88caadaff9da965ac49172b389427b574b27d4c64145851bc206d, neural-networks f87c70cb9d017c9a58161f94f304eb8e0cbe8f3c942747e2a17ef51a1075f161 +// spec sha256 t27-basics 4827f6b9f5d95ae98e1d49f037966d2cc826e07c691044f2f5fa1ee9c98ae474, course 8429472829c5d9a0782b2d2b21ff26879a429c5470f4abb5088f1e1a7fa674be, ai-numbers 7f736e357ef13446dfa8f978482cc28c7710caac3f7396769a8fc01b91e20802, goldenfloat d6b6019b8e6bf77a41991b32a3a3d1b5eb78ca4b7078e2bf5f5436df3dd7c59c, verify-hardware 7ca437575eaa8f8646f42c82b75862f091fb509708de152c4e18ed76ee39d4cf, clocks-and-cdc 7d491967f9326fcde194ab19a9bfa7f0ed960ba94d7ca3d82df0747e269c5acc, buses-and-peripherals 4dfdbd8c909d7ad8f1ac2d4f7025c77f0619ade92b181212ea9b589262695acc, ternary-computing e0a14010163f00208d5b54c800e6ce3f05e6b8581de94c0323097b00b1854437, arithmetic-and-dsp c2b6bfd642e88caadaff9da965ac49172b389427b574b27d4c64145851bc206d, neural-networks d6cffe6af3c2bd2ce3f73272eee7cca3e463f8f8e4e034d1dbc39f7f43083bc1 // Do not edit: change the .t27 source (or a Russian bundle) and regenerate. export const COURSES = [ @@ -11884,7 +11884,7 @@ export const COURSES = [ "publicSpec": "public/learn/neural-networks.t27", "ruContract": "specs/course/neural-networks-ru.t27", "ruBundle": "apps/website/i18n/neural-networks.ru.json", - "sha256": "f87c70cb9d017c9a58161f94f304eb8e0cbe8f3c942747e2a17ef51a1075f161", + "sha256": "d6cffe6af3c2bd2ce3f73272eee7cca3e463f8f8e4e034d1dbc39f7f43083bc1", "schemaVersion": 1, "gallery": "specs/widgets/gallery.t27" },
t27.aiEnglish
t27.aiEnglish

+Trinity S³AI +

XOR: a network learns what one neuron cannot

+

A 2-8-1 network trained by backpropagation in your browser: drag the epochs from 0 to 2000 and watch its four answers move to 0, 1, 1, 0 while the loss falls from 0.89 by twelve orders.

+
+Trinity S³AI +

Positional encoding: how a transformer knows word order

+

Every position gets 8 numbers, sines and cosines at frequencies falling by 10 per pair. Drag the position: the fast clock spins, the slow ones barely move, and the stripes show all 48 rows.

+
+Trinity S³AI +

LAMB: one learning rate for layers of every size

+

Scale a layer's weights and watch its LAMB step: it grows with the weight norm, so every layer moves by the same fraction of itself, until the norm passes 10 and the step stops growing.

+