fable 3.1.51 → 3.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +87 -2
  2. package/dist/fable.js +7 -5
  3. package/dist/fable.js.map +1 -1
  4. package/dist/fable.min.js +1 -1
  5. package/dist/fable.min.js.map +1 -1
  6. package/docs/.nojekyll +0 -0
  7. package/docs/README.md +95 -0
  8. package/docs/_sidebar.md +42 -0
  9. package/docs/architecture.md +326 -0
  10. package/docs/cover.md +11 -0
  11. package/docs/index.html +51 -0
  12. package/docs/services/README.md +76 -0
  13. package/docs/services/anticipate.md +331 -0
  14. package/docs/services/csv-parser.md +152 -0
  15. package/docs/services/data-format.md +277 -0
  16. package/docs/services/data-generation.md +142 -0
  17. package/docs/services/dates.md +216 -0
  18. package/docs/services/environment-data.md +44 -0
  19. package/docs/services/expression-parser-functions/README.md +178 -0
  20. package/docs/services/expression-parser-functions/abs.md +84 -0
  21. package/docs/services/expression-parser-functions/aggregationhistogram.md +83 -0
  22. package/docs/services/expression-parser-functions/aggregationhistogrambyobject.md +64 -0
  23. package/docs/services/expression-parser-functions/arrayconcat.md +64 -0
  24. package/docs/services/expression-parser-functions/avg.md +81 -0
  25. package/docs/services/expression-parser-functions/bucketset.md +69 -0
  26. package/docs/services/expression-parser-functions/ceil.md +70 -0
  27. package/docs/services/expression-parser-functions/cleanvaluearray.md +66 -0
  28. package/docs/services/expression-parser-functions/cleanvalueobject.md +68 -0
  29. package/docs/services/expression-parser-functions/compare.md +72 -0
  30. package/docs/services/expression-parser-functions/concat.md +73 -0
  31. package/docs/services/expression-parser-functions/concatraw.md +73 -0
  32. package/docs/services/expression-parser-functions/cos.md +75 -0
  33. package/docs/services/expression-parser-functions/count.md +73 -0
  34. package/docs/services/expression-parser-functions/countset.md +65 -0
  35. package/docs/services/expression-parser-functions/countsetelements.md +63 -0
  36. package/docs/services/expression-parser-functions/createarrayfromabsolutevalues.md +63 -0
  37. package/docs/services/expression-parser-functions/createvalueobjectbyhashes.md +69 -0
  38. package/docs/services/expression-parser-functions/cumulativesummation.md +96 -0
  39. package/docs/services/expression-parser-functions/dateadddays.md +79 -0
  40. package/docs/services/expression-parser-functions/dateaddhours.md +74 -0
  41. package/docs/services/expression-parser-functions/dateaddmilliseconds.md +65 -0
  42. package/docs/services/expression-parser-functions/dateaddminutes.md +72 -0
  43. package/docs/services/expression-parser-functions/dateaddmonths.md +74 -0
  44. package/docs/services/expression-parser-functions/dateaddseconds.md +66 -0
  45. package/docs/services/expression-parser-functions/dateaddweeks.md +73 -0
  46. package/docs/services/expression-parser-functions/dateaddyears.md +74 -0
  47. package/docs/services/expression-parser-functions/datedaydifference.md +84 -0
  48. package/docs/services/expression-parser-functions/datefromparts.md +81 -0
  49. package/docs/services/expression-parser-functions/datehourdifference.md +64 -0
  50. package/docs/services/expression-parser-functions/datemathadd.md +72 -0
  51. package/docs/services/expression-parser-functions/datemilliseconddifference.md +64 -0
  52. package/docs/services/expression-parser-functions/dateminutedifference.md +64 -0
  53. package/docs/services/expression-parser-functions/datemonthdifference.md +66 -0
  54. package/docs/services/expression-parser-functions/dateseconddifference.md +64 -0
  55. package/docs/services/expression-parser-functions/dateweekdifference.md +65 -0
  56. package/docs/services/expression-parser-functions/dateyeardifference.md +64 -0
  57. package/docs/services/expression-parser-functions/distributionhistogram.md +96 -0
  58. package/docs/services/expression-parser-functions/distributionhistogrambyobject.md +64 -0
  59. package/docs/services/expression-parser-functions/entryinset.md +72 -0
  60. package/docs/services/expression-parser-functions/euler.md +77 -0
  61. package/docs/services/expression-parser-functions/exp.md +74 -0
  62. package/docs/services/expression-parser-functions/findfirstvaluebyexactmatch.md +67 -0
  63. package/docs/services/expression-parser-functions/findfirstvaluebystringincludes.md +67 -0
  64. package/docs/services/expression-parser-functions/flatten.md +76 -0
  65. package/docs/services/expression-parser-functions/floor.md +70 -0
  66. package/docs/services/expression-parser-functions/gaussianelimination.md +75 -0
  67. package/docs/services/expression-parser-functions/generatearrayofobjectsfromsets.md +70 -0
  68. package/docs/services/expression-parser-functions/getvalue.md +90 -0
  69. package/docs/services/expression-parser-functions/getvaluearray.md +64 -0
  70. package/docs/services/expression-parser-functions/getvalueobject.md +67 -0
  71. package/docs/services/expression-parser-functions/if.md +109 -0
  72. package/docs/services/expression-parser-functions/iterativeseries.md +107 -0
  73. package/docs/services/expression-parser-functions/join.md +75 -0
  74. package/docs/services/expression-parser-functions/joinraw.md +64 -0
  75. package/docs/services/expression-parser-functions/largestinset.md +63 -0
  76. package/docs/services/expression-parser-functions/leastsquares.md +66 -0
  77. package/docs/services/expression-parser-functions/linest.md +58 -0
  78. package/docs/services/expression-parser-functions/log.md +74 -0
  79. package/docs/services/expression-parser-functions/match.md +71 -0
  80. package/docs/services/expression-parser-functions/matrixinverse.md +67 -0
  81. package/docs/services/expression-parser-functions/matrixmultiply.md +71 -0
  82. package/docs/services/expression-parser-functions/matrixtranspose.md +72 -0
  83. package/docs/services/expression-parser-functions/matrixvectormultiply.md +69 -0
  84. package/docs/services/expression-parser-functions/max.md +73 -0
  85. package/docs/services/expression-parser-functions/mean.md +63 -0
  86. package/docs/services/expression-parser-functions/median.md +79 -0
  87. package/docs/services/expression-parser-functions/min.md +73 -0
  88. package/docs/services/expression-parser-functions/mode.md +66 -0
  89. package/docs/services/expression-parser-functions/objectkeystoarray.md +66 -0
  90. package/docs/services/expression-parser-functions/objectvaluessortbyexternalobjectarray.md +65 -0
  91. package/docs/services/expression-parser-functions/objectvaluestoarray.md +67 -0
  92. package/docs/services/expression-parser-functions/percent.md +75 -0
  93. package/docs/services/expression-parser-functions/pi.md +77 -0
  94. package/docs/services/expression-parser-functions/polynomialregression.md +69 -0
  95. package/docs/services/expression-parser-functions/predict.md +71 -0
  96. package/docs/services/expression-parser-functions/rad.md +85 -0
  97. package/docs/services/expression-parser-functions/randomfloat.md +63 -0
  98. package/docs/services/expression-parser-functions/randomfloatbetween.md +72 -0
  99. package/docs/services/expression-parser-functions/randomfloatupto.md +65 -0
  100. package/docs/services/expression-parser-functions/randominteger.md +56 -0
  101. package/docs/services/expression-parser-functions/randomintegerbetween.md +72 -0
  102. package/docs/services/expression-parser-functions/randomintegerupto.md +64 -0
  103. package/docs/services/expression-parser-functions/resolvehtmlentities.md +64 -0
  104. package/docs/services/expression-parser-functions/round.md +111 -0
  105. package/docs/services/expression-parser-functions/setconcatenate.md +64 -0
  106. package/docs/services/expression-parser-functions/sin.md +83 -0
  107. package/docs/services/expression-parser-functions/slice.md +80 -0
  108. package/docs/services/expression-parser-functions/smallestinset.md +63 -0
  109. package/docs/services/expression-parser-functions/sorthistogram.md +70 -0
  110. package/docs/services/expression-parser-functions/sorthistogrambykeys.md +69 -0
  111. package/docs/services/expression-parser-functions/sortset.md +75 -0
  112. package/docs/services/expression-parser-functions/sqrt.md +85 -0
  113. package/docs/services/expression-parser-functions/stdev.md +81 -0
  114. package/docs/services/expression-parser-functions/stdeva.md +58 -0
  115. package/docs/services/expression-parser-functions/stdevp.md +83 -0
  116. package/docs/services/expression-parser-functions/stringcountsegments.md +66 -0
  117. package/docs/services/expression-parser-functions/stringgetsegments.md +74 -0
  118. package/docs/services/expression-parser-functions/subtractingsummation.md +66 -0
  119. package/docs/services/expression-parser-functions/sum.md +78 -0
  120. package/docs/services/expression-parser-functions/tan.md +78 -0
  121. package/docs/services/expression-parser-functions/tofixed.md +75 -0
  122. package/docs/services/expression-parser-functions/var.md +67 -0
  123. package/docs/services/expression-parser-functions/vara.md +58 -0
  124. package/docs/services/expression-parser-functions/varp.md +66 -0
  125. package/docs/services/expression-parser-functions/when.md +98 -0
  126. package/docs/services/expression-parser.md +314 -0
  127. package/docs/services/file-persistence.md +279 -0
  128. package/docs/services/logging.md +237 -0
  129. package/docs/services/logic.md +166 -0
  130. package/docs/services/manifest.md +256 -0
  131. package/docs/services/math.md +279 -0
  132. package/docs/services/meta-template.md +268 -0
  133. package/docs/services/object-cache.md +171 -0
  134. package/docs/services/operation.md +207 -0
  135. package/docs/services/progress-time.md +167 -0
  136. package/docs/services/progress-tracker-set.md +222 -0
  137. package/docs/services/rest-client.md +296 -0
  138. package/docs/services/settings-manager.md +265 -0
  139. package/docs/services/template.md +233 -0
  140. package/docs/services/utility.md +304 -0
  141. package/docs/services/uuid.md +162 -0
  142. package/package.json +1 -1
  143. package/source/services/Fable-Service-DataFormat.js +1 -0
  144. package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-ValueMarshal.js +6 -4
  145. package/test/ExpressionParser_tests.js +3 -0
@@ -0,0 +1,265 @@
1
+ # Settings Manager Service
2
+
3
+ The Settings Manager provides centralized configuration management for Fable applications, with support for environment-aware settings and default value merging.
4
+
5
+ ## Access
6
+
7
+ ```javascript
8
+ // Pre-initialized, available directly
9
+ fable.SettingsManager
10
+ fable.settings // Shorthand for SettingsManager.settings
11
+ fable.settingsManager // Alias
12
+ ```
13
+
14
+ ## Basic Usage
15
+
16
+ ### Reading Settings
17
+
18
+ ```javascript
19
+ // Access settings directly
20
+ const productName = fable.settings.Product;
21
+ const version = fable.settings.ProductVersion;
22
+
23
+ // Access nested settings
24
+ const dbHost = fable.settings.Database.Host;
25
+ ```
26
+
27
+ ### Providing Configuration
28
+
29
+ Pass settings when creating a Fable instance:
30
+
31
+ ```javascript
32
+ const fable = new Fable({
33
+ Product: 'MyApplication',
34
+ ProductVersion: '1.0.0',
35
+
36
+ Database: {
37
+ Host: 'localhost',
38
+ Port: 5432,
39
+ Name: 'myapp'
40
+ },
41
+
42
+ API: {
43
+ BaseURL: 'https://api.example.com',
44
+ Timeout: 30000
45
+ }
46
+ });
47
+ ```
48
+
49
+ ## Default Settings
50
+
51
+ Fable provides sensible defaults that your configuration extends:
52
+
53
+ ```javascript
54
+ {
55
+ Product: 'Fable',
56
+ ProductVersion: '0.0.0',
57
+
58
+ UUID: {
59
+ DataCenter: 0,
60
+ Worker: 0
61
+ },
62
+
63
+ LogStreams: [
64
+ { level: 'info' }
65
+ ]
66
+ }
67
+ ```
68
+
69
+ Your settings are merged with these defaults using [precedent](https://github.com/stevenvelozo/precedent).
70
+
71
+ ## Environment-Aware Configuration
72
+
73
+ ### Using Environment Variables
74
+
75
+ ```javascript
76
+ const fable = new Fable({
77
+ Product: 'MyApp',
78
+
79
+ Database: {
80
+ Host: process.env.DB_HOST || 'localhost',
81
+ Port: parseInt(process.env.DB_PORT) || 5432,
82
+ Password: process.env.DB_PASSWORD
83
+ }
84
+ });
85
+ ```
86
+
87
+ ### Environment-Specific Config Files
88
+
89
+ ```javascript
90
+ const environment = process.env.NODE_ENV || 'development';
91
+ const config = require(`./config/${environment}.json`);
92
+
93
+ const fable = new Fable(config);
94
+ ```
95
+
96
+ ## Precedent Integration
97
+
98
+ The Settings Manager uses precedent for deep configuration merging:
99
+
100
+ ```javascript
101
+ // Base configuration
102
+ const baseConfig = {
103
+ API: {
104
+ Timeout: 5000,
105
+ RetryCount: 3
106
+ }
107
+ };
108
+
109
+ // Environment override
110
+ const envConfig = {
111
+ API: {
112
+ Timeout: 30000 // Override just the timeout
113
+ }
114
+ };
115
+
116
+ // Result: { API: { Timeout: 30000, RetryCount: 3 } }
117
+ ```
118
+
119
+ ## Configuration Patterns
120
+
121
+ ### Layered Configuration
122
+
123
+ ```javascript
124
+ const defaults = require('./config/default.json');
125
+ const environment = require(`./config/${process.env.NODE_ENV}.json`);
126
+ const local = require('./config/local.json'); // gitignored
127
+
128
+ const fable = new Fable({
129
+ ...defaults,
130
+ ...environment,
131
+ ...local
132
+ });
133
+ ```
134
+
135
+ ### Feature Flags
136
+
137
+ ```javascript
138
+ const fable = new Fable({
139
+ Features: {
140
+ NewDashboard: process.env.FEATURE_NEW_DASHBOARD === 'true',
141
+ BetaAPI: false
142
+ }
143
+ });
144
+
145
+ // Usage
146
+ if (fable.settings.Features.NewDashboard) {
147
+ // New dashboard code
148
+ }
149
+ ```
150
+
151
+ ### Service Configuration
152
+
153
+ ```javascript
154
+ const fable = new Fable({
155
+ Services: {
156
+ Email: {
157
+ Provider: 'sendgrid',
158
+ APIKey: process.env.SENDGRID_API_KEY
159
+ },
160
+ Storage: {
161
+ Provider: 's3',
162
+ Bucket: 'my-app-storage'
163
+ }
164
+ }
165
+ });
166
+ ```
167
+
168
+ ## Accessing Settings in Services
169
+
170
+ All Fable services can access settings:
171
+
172
+ ```javascript
173
+ class MyService extends libFableServiceBase {
174
+ constructor(pFable, pOptions, pServiceHash) {
175
+ super(pFable, pOptions, pServiceHash);
176
+
177
+ // Access global settings
178
+ this.apiUrl = this.fable.settings.API.BaseURL;
179
+
180
+ // Access service-specific options
181
+ this.localOption = this.options.myOption;
182
+ }
183
+ }
184
+ ```
185
+
186
+ ## Common Configuration Options
187
+
188
+ ### Product Information
189
+
190
+ ```javascript
191
+ {
192
+ Product: 'MyApp',
193
+ ProductVersion: '1.0.0'
194
+ }
195
+ ```
196
+
197
+ ### UUID Configuration
198
+
199
+ ```javascript
200
+ {
201
+ UUID: {
202
+ DataCenter: 1, // 0-31
203
+ Worker: 5 // 0-31
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### Logging Configuration
209
+
210
+ ```javascript
211
+ {
212
+ LogStreams: [
213
+ { level: 'info' },
214
+ { level: 'error', path: '/var/log/app/error.log' }
215
+ ]
216
+ }
217
+ ```
218
+
219
+ ### REST Client Configuration
220
+
221
+ ```javascript
222
+ {
223
+ RestClientURLPrefix: 'https://api.example.com/v1'
224
+ }
225
+ ```
226
+
227
+ ## Best Practices
228
+
229
+ 1. **Don't hardcode secrets**: Use environment variables
230
+ 2. **Use typed configuration**: Define interfaces for your config shape
231
+ 3. **Provide sensible defaults**: Make configuration optional where possible
232
+ 4. **Document your settings**: List all configuration options
233
+ 5. **Validate on startup**: Check for required settings early
234
+
235
+ ```javascript
236
+ // Validation example
237
+ const fable = new Fable(config);
238
+
239
+ if (!fable.settings.Database?.Host) {
240
+ throw new Error('Database.Host is required');
241
+ }
242
+ ```
243
+
244
+ ## Reading External Config Files
245
+
246
+ ```javascript
247
+ const fs = require('fs');
248
+ const path = require('path');
249
+
250
+ const configPath = path.join(__dirname, 'config.json');
251
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
252
+
253
+ const fable = new Fable(config);
254
+ ```
255
+
256
+ ## Runtime Configuration Updates
257
+
258
+ While generally not recommended, settings can be modified at runtime:
259
+
260
+ ```javascript
261
+ // Not recommended, but possible
262
+ fable.settings.MyFeature.Enabled = true;
263
+
264
+ // Better: Use a service for dynamic configuration
265
+ ```
@@ -0,0 +1,233 @@
1
+ # Template Service
2
+
3
+ The Template service provides underscore/lodash-style template compilation and rendering. It compiles string templates into reusable functions.
4
+
5
+ ## Access
6
+
7
+ ```javascript
8
+ // On-demand service - instantiate when needed
9
+ const template = fable.instantiateServiceProvider('Template');
10
+
11
+ // Or use the Utility service shorthand
12
+ const renderFn = fable.Utility.template('Hello, <%= name %>!');
13
+ ```
14
+
15
+ ## Template Syntax
16
+
17
+ ### Interpolation (`<%= %>`)
18
+
19
+ Output a value:
20
+
21
+ ```javascript
22
+ const template = fable.instantiateServiceProvider('Template');
23
+ const render = template.buildTemplateFunction('Hello, <%= name %>!');
24
+
25
+ render({ name: 'World' }); // Returns 'Hello, World!'
26
+ ```
27
+
28
+ ### Evaluation (`<% %>`)
29
+
30
+ Execute JavaScript code:
31
+
32
+ ```javascript
33
+ const render = template.buildTemplateFunction(`
34
+ <% for (var i = 0; i < items.length; i++) { %>
35
+ Item: <%= items[i] %>
36
+ <% } %>
37
+ `);
38
+
39
+ render({ items: ['Apple', 'Banana', 'Cherry'] });
40
+ ```
41
+
42
+ ## Basic Usage
43
+
44
+ ### Create and Use Template
45
+
46
+ ```javascript
47
+ const template = fable.instantiateServiceProvider('Template');
48
+
49
+ // Build the template function
50
+ const greetingTemplate = template.buildTemplateFunction('Hello, <%= name %>!');
51
+
52
+ // Use it multiple times
53
+ greetingTemplate({ name: 'Alice' }); // 'Hello, Alice!'
54
+ greetingTemplate({ name: 'Bob' }); // 'Hello, Bob!'
55
+ ```
56
+
57
+ ### Immediate Rendering
58
+
59
+ Pass data as the second argument to render immediately:
60
+
61
+ ```javascript
62
+ const result = template.buildTemplateFunction('Sum: <%= a + b %>', { a: 5, b: 3 });
63
+ // Returns 'Sum: 8'
64
+ ```
65
+
66
+ ## Using the Utility Shorthand
67
+
68
+ The Utility service provides a convenient wrapper:
69
+
70
+ ```javascript
71
+ // Create a template function
72
+ const greet = fable.Utility.template('Hello, <%= name %>!');
73
+ greet({ name: 'World' });
74
+
75
+ // Or render immediately
76
+ fable.Utility.template('Hello, <%= name %>!', { name: 'World' });
77
+ ```
78
+
79
+ ### Hashed Templates
80
+
81
+ Register templates for reuse by name:
82
+
83
+ ```javascript
84
+ // Register a template
85
+ fable.Utility.buildHashedTemplate('user-card', `
86
+ <div class="card">
87
+ <h2><%= user.name %></h2>
88
+ <p><%= user.email %></p>
89
+ </div>
90
+ `);
91
+
92
+ // Use the registered template
93
+ fable.Utility.templates['user-card']({ user: { name: 'John', email: 'john@example.com' } });
94
+ ```
95
+
96
+ ## Examples
97
+
98
+ ### HTML Generation
99
+
100
+ ```javascript
101
+ const cardTemplate = template.buildTemplateFunction(`
102
+ <div class="card">
103
+ <h2><%= title %></h2>
104
+ <p><%= description %></p>
105
+ <% if (showButton) { %>
106
+ <button><%= buttonText %></button>
107
+ <% } %>
108
+ </div>
109
+ `);
110
+
111
+ cardTemplate({
112
+ title: 'Welcome',
113
+ description: 'This is a card component',
114
+ showButton: true,
115
+ buttonText: 'Click Me'
116
+ });
117
+ ```
118
+
119
+ ### Lists and Loops
120
+
121
+ ```javascript
122
+ const listTemplate = template.buildTemplateFunction(`
123
+ <ul>
124
+ <% for (var i = 0; i < items.length; i++) { %>
125
+ <li><%= items[i].name %>: $<%= items[i].price %></li>
126
+ <% } %>
127
+ </ul>
128
+ `);
129
+
130
+ listTemplate({
131
+ items: [
132
+ { name: 'Apple', price: 1.50 },
133
+ { name: 'Banana', price: 0.75 }
134
+ ]
135
+ });
136
+ ```
137
+
138
+ ### Conditional Content
139
+
140
+ ```javascript
141
+ const statusTemplate = template.buildTemplateFunction(`
142
+ <% if (status === 'active') { %>
143
+ <span class="badge-green">Active</span>
144
+ <% } else if (status === 'pending') { %>
145
+ <span class="badge-yellow">Pending</span>
146
+ <% } else { %>
147
+ <span class="badge-red">Inactive</span>
148
+ <% } %>
149
+ `);
150
+
151
+ statusTemplate({ status: 'active' });
152
+ ```
153
+
154
+ ### Nested Data
155
+
156
+ ```javascript
157
+ const profileTemplate = template.buildTemplateFunction(`
158
+ <div class="profile">
159
+ <h1><%= user.name %></h1>
160
+ <p>Email: <%= user.contact.email %></p>
161
+ <p>Phone: <%= user.contact.phone %></p>
162
+ <h3>Addresses:</h3>
163
+ <% for (var i = 0; i < user.addresses.length; i++) { %>
164
+ <p><%= user.addresses[i].street %>, <%= user.addresses[i].city %></p>
165
+ <% } %>
166
+ </div>
167
+ `);
168
+
169
+ profileTemplate({
170
+ user: {
171
+ name: 'John Doe',
172
+ contact: {
173
+ email: 'john@example.com',
174
+ phone: '555-1234'
175
+ },
176
+ addresses: [
177
+ { street: '123 Main St', city: 'Anytown' },
178
+ { street: '456 Oak Ave', city: 'Other City' }
179
+ ]
180
+ }
181
+ });
182
+ ```
183
+
184
+ ### Print Function
185
+
186
+ Use `print()` for inline output:
187
+
188
+ ```javascript
189
+ const template = template.buildTemplateFunction(`
190
+ <% print('Hello'); print(' '); print('World'); %>
191
+ `);
192
+
193
+ template({}); // Returns 'Hello World'
194
+ ```
195
+
196
+ ## Template Source Access
197
+
198
+ After building a template, you can access the generated source:
199
+
200
+ ```javascript
201
+ const tpl = fable.instantiateServiceProvider('Template');
202
+ tpl.buildTemplateFunction('Hello, <%= name %>!');
203
+
204
+ // Access the generated function source
205
+ console.log(tpl.TemplateSource);
206
+ console.log(tpl.TemplateSourceCompiled);
207
+ ```
208
+
209
+ ## Escape Handling
210
+
211
+ The template engine handles these escape sequences:
212
+
213
+ - `\\` - Backslash
214
+ - `'` - Single quote
215
+ - `\r` - Carriage return
216
+ - `\n` - Newline
217
+ - `\t` - Tab
218
+ - `\u2028` - Line separator
219
+ - `\u2029` - Paragraph separator
220
+
221
+ ## Notes
222
+
223
+ - This implementation is compatible with underscore/lodash template syntax
224
+ - Does NOT implement underscore's escape expressions (`<%- %>`)
225
+ - Does NOT implement automatic browser variable assignment
226
+ - Templates are compiled to JavaScript functions for performance
227
+ - URL-encoded content in templates is automatically decoded
228
+
229
+ ## Performance Tips
230
+
231
+ 1. **Compile once, use many times**: Store template functions and reuse them
232
+ 2. **Use hashed templates**: For frequently used templates, register them with `buildHashedTemplate`
233
+ 3. **Avoid complex logic**: Keep template logic simple; move complex operations to the data preparation phase