harmony 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.gitignore +5 -0
  2. data/LICENSE +19 -0
  3. data/Manifest +117 -0
  4. data/README.md +155 -0
  5. data/Rakefile +39 -0
  6. data/docs.watchr +25 -0
  7. data/harmony.gemspec +18 -0
  8. data/lib/harmony.rb +5 -0
  9. data/lib/harmony/page.rb +123 -0
  10. data/specs.watchr +36 -0
  11. data/test/harmony_test.rb +8 -0
  12. data/test/page_test.rb +73 -0
  13. data/test/test_helper.rb +13 -0
  14. data/vendor/README +1 -0
  15. data/vendor/envjs/README +36 -0
  16. data/vendor/envjs/bin/envjsrb +255 -0
  17. data/vendor/envjs/bin/jquery-1.2.6-test.js +33 -0
  18. data/vendor/envjs/bin/jquery-1.3.1-test.js +33 -0
  19. data/vendor/envjs/bin/jquery-1.3.2-test.js +106 -0
  20. data/vendor/envjs/bin/prototype-1.6.0.3-test.js +82 -0
  21. data/vendor/envjs/bin/prototype_1.6.0.3_tmpl.txt +27 -0
  22. data/vendor/envjs/bin/test-jquery.sh +58 -0
  23. data/vendor/envjs/bin/test-prototype.sh +54 -0
  24. data/vendor/envjs/bin/tidy +0 -0
  25. data/vendor/envjs/lib/envjs.rb +23 -0
  26. data/vendor/envjs/lib/envjs/env.js +21665 -0
  27. data/vendor/envjs/lib/envjs/net.rb +3 -0
  28. data/vendor/envjs/lib/envjs/net/cgi.rb +94 -0
  29. data/vendor/envjs/lib/envjs/net/file.rb +75 -0
  30. data/vendor/envjs/lib/envjs/options.rb +11 -0
  31. data/vendor/envjs/lib/envjs/runtime.rb +351 -0
  32. data/vendor/envjs/lib/envjs/tempfile.rb +24 -0
  33. data/vendor/envjs/test/base64.js +80 -0
  34. data/vendor/envjs/test/call-load-test.js +15 -0
  35. data/vendor/envjs/test/data.js +45 -0
  36. data/vendor/envjs/test/debug.js +53 -0
  37. data/vendor/envjs/test/firebug/errorIcon.png +0 -0
  38. data/vendor/envjs/test/firebug/firebug.css +209 -0
  39. data/vendor/envjs/test/firebug/firebug.html +23 -0
  40. data/vendor/envjs/test/firebug/firebug.js +672 -0
  41. data/vendor/envjs/test/firebug/firebugx.js +10 -0
  42. data/vendor/envjs/test/firebug/infoIcon.png +0 -0
  43. data/vendor/envjs/test/firebug/warningIcon.png +0 -0
  44. data/vendor/envjs/test/fixtures/html/events.html +171 -0
  45. data/vendor/envjs/test/fixtures/html/iframe1.html +46 -0
  46. data/vendor/envjs/test/fixtures/html/iframe1a.html +46 -0
  47. data/vendor/envjs/test/fixtures/html/iframe2.html +45 -0
  48. data/vendor/envjs/test/fixtures/html/iframe3.html +28 -0
  49. data/vendor/envjs/test/fixtures/html/iframeN.html +57 -0
  50. data/vendor/envjs/test/fixtures/html/malformed.html +181 -0
  51. data/vendor/envjs/test/fixtures/html/scope.html +81 -0
  52. data/vendor/envjs/test/fixtures/html/trivial.html +19 -0
  53. data/vendor/envjs/test/fixtures/html/with_js.html +26 -0
  54. data/vendor/envjs/test/fixtures/images/icon-blue.png +0 -0
  55. data/vendor/envjs/test/fixtures/js/external_script.js +1 -0
  56. data/vendor/envjs/test/fixtures/js/script.js +1 -0
  57. data/vendor/envjs/test/fixtures/js/script_error.js +2 -0
  58. data/vendor/envjs/test/html/events.html +171 -0
  59. data/vendor/envjs/test/html/iframe1.html +46 -0
  60. data/vendor/envjs/test/html/iframe1a.html +46 -0
  61. data/vendor/envjs/test/html/iframe2.html +45 -0
  62. data/vendor/envjs/test/html/iframe3.html +30 -0
  63. data/vendor/envjs/test/html/iframeN.html +57 -0
  64. data/vendor/envjs/test/html/malformed.html +181 -0
  65. data/vendor/envjs/test/html/scope.html +87 -0
  66. data/vendor/envjs/test/html/script.js +1 -0
  67. data/vendor/envjs/test/html/trivial.html +19 -0
  68. data/vendor/envjs/test/html/with_js.html +26 -0
  69. data/vendor/envjs/test/index.html +328 -0
  70. data/vendor/envjs/test/java-prototype.js +9 -0
  71. data/vendor/envjs/test/primary-tests.js +24 -0
  72. data/vendor/envjs/test/prototype-test.js +13 -0
  73. data/vendor/envjs/test/qunit.js +61 -0
  74. data/vendor/envjs/test/qunit/qunit/qunit.css +17 -0
  75. data/vendor/envjs/test/qunit/qunit/qunit.js +997 -0
  76. data/vendor/envjs/test/scope.rb +25 -0
  77. data/vendor/envjs/test/specs/dist/env.spec.js +1534 -0
  78. data/vendor/envjs/test/specs/envjs.spec.css +46 -0
  79. data/vendor/envjs/test/specs/parser/html.js +31 -0
  80. data/vendor/envjs/test/specs/parser/spec.html +40 -0
  81. data/vendor/envjs/test/specs/parser/xml.js +31 -0
  82. data/vendor/envjs/test/specs/qunit.bdd.js +210 -0
  83. data/vendor/envjs/test/specs/qunit.css +17 -0
  84. data/vendor/envjs/test/specs/qunit.js +997 -0
  85. data/vendor/envjs/test/specs/template/spec-0.js +31 -0
  86. data/vendor/envjs/test/specs/template/spec-1.js +31 -0
  87. data/vendor/envjs/test/specs/template/spec.html +40 -0
  88. data/vendor/envjs/test/specs/window/css.js +23 -0
  89. data/vendor/envjs/test/specs/window/dialog.js +25 -0
  90. data/vendor/envjs/test/specs/window/document.js +23 -0
  91. data/vendor/envjs/test/specs/window/event.js +25 -0
  92. data/vendor/envjs/test/specs/window/history.js +34 -0
  93. data/vendor/envjs/test/specs/window/location.js +34 -0
  94. data/vendor/envjs/test/specs/window/navigator.js +71 -0
  95. data/vendor/envjs/test/specs/window/screen.js +42 -0
  96. data/vendor/envjs/test/specs/window/spec.html +48 -0
  97. data/vendor/envjs/test/specs/window/timer.js +26 -0
  98. data/vendor/envjs/test/specs/window/window.js +53 -0
  99. data/vendor/envjs/test/specs/xhr/spec.html +47 -0
  100. data/vendor/envjs/test/specs/xhr/xhr.js +31 -0
  101. data/vendor/envjs/test/test.js +10 -0
  102. data/vendor/envjs/test/unit/dom.js +44 -0
  103. data/vendor/envjs/test/unit/elementmembers.js +60 -0
  104. data/vendor/envjs/test/unit/events.js +195 -0
  105. data/vendor/envjs/test/unit/fixtures/external_script.js +1 -0
  106. data/vendor/envjs/test/unit/iframe.js +234 -0
  107. data/vendor/envjs/test/unit/multi-window.js +212 -0
  108. data/vendor/envjs/test/unit/nu.validator.js +34 -0
  109. data/vendor/envjs/test/unit/onload.js +90 -0
  110. data/vendor/envjs/test/unit/parser.js +121 -0
  111. data/vendor/envjs/test/unit/prototypecompat.js +22 -0
  112. data/vendor/envjs/test/unit/proxy.js +6 -0
  113. data/vendor/envjs/test/unit/scope.js +209 -0
  114. data/vendor/envjs/test/unit/timer.js +115 -0
  115. data/vendor/envjs/test/unit/window.js +41 -0
  116. data/vendor/envjs/test/vendor/jQuery/README +2 -0
  117. data/vendor/envjs/test/vendor/prototype-1.6.0.3.js +4320 -0
  118. metadata +200 -0
@@ -0,0 +1,3 @@
1
+ require 'envjs'
2
+
3
+ module Envjs::Net; end
@@ -0,0 +1,94 @@
1
+ require 'net/protocol'
2
+
3
+ require 'envjs/net'
4
+
5
+ class Envjs::Net::CGI
6
+
7
+ def save_and_set k, v
8
+ @saved[k] = ENV[k]
9
+ ENV[k] = v
10
+ end
11
+
12
+ def restore
13
+ @saved.keys.each do |k|
14
+ ENV[k] = @saved[k]
15
+ end
16
+ @saved = {}
17
+ end
18
+
19
+ def initialize xhr, data
20
+ if (match = %r((.*\.php)(\?(.*))?).match xhr.url).nil?
21
+ raise "Not CGI"
22
+ end
23
+
24
+ @saved = {}
25
+
26
+ begin
27
+
28
+ # p match[0]
29
+
30
+ path = match[1]
31
+ path.sub! %r(^file://), ""
32
+
33
+ save_and_set( "GATEWAY_INTERFACE", "CGI/1.1" )
34
+
35
+ save_and_set( "REQUEST_METHOD", xhr["method"] )
36
+ if ( match[3] )
37
+ save_and_set( "QUERY_STRING", match[3] )
38
+ end
39
+
40
+ if ct = xhr["headers"]["Content-Type"]
41
+ save_and_set( "CONTENT_TYPE", ct )
42
+ end
43
+
44
+ if data
45
+ save_and_set( "CONTENT_LENGTH", data.length.to_s )
46
+ end
47
+
48
+ xhr["headers"].each do |k,v|
49
+ k.gsub!("-","_")
50
+ k = "HTTP_" + k
51
+ save_and_set( k, v )
52
+ end
53
+
54
+ result = nil
55
+
56
+ save_and_set( "PATH_INFO", path )
57
+ save_and_set( "PATH_TRANSLATED", path )
58
+ save_and_set( "REDIRECT_STATUS", "200" )
59
+
60
+ open("|php-cgi", "r+") do |php|
61
+ if data
62
+ php.write data
63
+ php.flush
64
+ end
65
+ result = php.read
66
+ end
67
+
68
+ result && result = result.split("\r\n")
69
+ @headers = {}
70
+ while line = result.shift
71
+ break if line == ""
72
+ match = /([^:]*):\s*(.*)/.match line
73
+ @headers[match[1]]=match[2]
74
+ end
75
+ # p "q", result.join("\r\n")
76
+ @body = result.join("\r\n")
77
+ ensure
78
+ restore
79
+ end
80
+
81
+ end
82
+
83
+ def each
84
+ @headers.each do |k,v|
85
+ yield k, v
86
+ end
87
+ end
88
+
89
+ def finish
90
+ end
91
+
92
+ attr_reader :body
93
+
94
+ end
@@ -0,0 +1,75 @@
1
+ require 'net/protocol'
2
+
3
+ require 'envjs/net'
4
+
5
+ class Envjs::Net::File < Net::Protocol
6
+
7
+ class << self
8
+ attr_accessor :on_open
9
+ end
10
+
11
+ class Get
12
+ attr_accessor :path
13
+ def initialize path
14
+ @path = path
15
+ end
16
+ end
17
+
18
+ def initialize host, port
19
+ end
20
+
21
+ def self.start host, port
22
+ new( host, port ).start
23
+ end
24
+
25
+ def start
26
+ self
27
+ end
28
+
29
+ def finish
30
+ end
31
+
32
+ def request request
33
+ Response.new request.path
34
+ end
35
+
36
+ class Response
37
+ def initialize path
38
+ @path = path
39
+ on_open = Envjs::Net::File.on_open
40
+ on_open and on_open.call( path )
41
+ @file = File.new @path
42
+ @body = @file.read
43
+ @code = @file.nil? ? "404" : "200";
44
+ @file.close
45
+ end
46
+
47
+ def [] *args
48
+ nil
49
+ end
50
+
51
+ def each &block
52
+ end
53
+
54
+ def getHeaderFields
55
+ []
56
+ end
57
+
58
+ def getContentEncoding
59
+ nil
60
+ end
61
+
62
+ def getResponseCode
63
+ @file.nil? ? 404 : 200;
64
+ end
65
+
66
+
67
+ def getInputStream
68
+ self
69
+ end
70
+
71
+ attr_reader :body, :code
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,11 @@
1
+ require 'optparse'
2
+
3
+ $envjsrb_deps = nil
4
+
5
+ OptionParser.new do |o|
6
+
7
+ o.on("--deps path") do |path|
8
+ $envjsrb_deps = path
9
+ end
10
+
11
+ end.parse!
@@ -0,0 +1,351 @@
1
+ require 'envjs'
2
+ require "open-uri"
3
+ require 'pathname'
4
+ begin
5
+ require 'fsdb'
6
+ rescue LoadError; end
7
+ require 'envjs/net/file'
8
+
9
+ module Envjs::Runtime
10
+
11
+ def self.extended object
12
+ object.instance_eval do
13
+
14
+ evaluate <<'EOJS'
15
+ print = function() {
16
+ var l = arguments.length
17
+ for( var i = 0; i < l; i++ ) {
18
+ var s;
19
+ if ( arguments[i] === null ) {
20
+ s = "null";
21
+ } else if ( arguments[i] === undefined ) {
22
+ s = "undefined"
23
+ } else {
24
+ s = arguments[i].toString();
25
+ }
26
+ Ruby.print(s);
27
+ if( i < l-1 ) {
28
+ Ruby.print(" ");
29
+ }
30
+ }
31
+ Ruby.print("\n");
32
+ Ruby['$stdout'].flush();
33
+ };
34
+ EOJS
35
+
36
+ evaluate <<'EOJS'
37
+ debug = function() {
38
+ var l = arguments.length
39
+ for( var i = 0; i < l; i++ ) {
40
+ var s;
41
+ if ( arguments[i] === null ) {
42
+ s = "null";
43
+ } else if ( arguments[i] === undefined ) {
44
+ s = "undefined"
45
+ } else {
46
+ s = arguments[i].toString();
47
+ }
48
+ Ruby['$stderr'].print(s);
49
+ if( i < l-1 ) {
50
+ Ruby['$stderr'].print(" ");
51
+ }
52
+ }
53
+ Ruby['$stderr'].print("\n");
54
+ };
55
+ EOJS
56
+
57
+ evaluate <<'EOJS'
58
+ puts = function() {
59
+ var l = arguments.length
60
+ for( var i = 0; i < l; i++ ) {
61
+ var s;
62
+ if ( arguments[i] === null ) {
63
+ s = "null";
64
+ } else if ( arguments[i] === undefined ) {
65
+ s = "undefined"
66
+ } else {
67
+ s = arguments[i].toString();
68
+ }
69
+ Ruby.print(s);
70
+ Ruby.eval("$stdout.flush")
71
+ }
72
+ };
73
+ EOJS
74
+
75
+ master = global["$master"] = evaluate("new Object")
76
+ master.symbols = [ "Johnson", "Ruby", "print", "debug", "puts", "load", "reload", "whichInterpreter", "multiwindow" ]
77
+ master.symbols.each { |symbol| master[symbol] = global[symbol] }
78
+
79
+ master.whichInterpreter = "Johnson"
80
+
81
+ master.multiwindow = true
82
+
83
+ # calling this from JS is hosed; the ruby side is confused, maybe because HTTPHeaders is mixed in?
84
+ master.add_req_field = lambda { |r,k,v| r.add_field(k,v) }
85
+
86
+ db = lambda do
87
+ $envjsrb_deps && ( @db ||= FSDB::Database.new $envjsrb_deps )
88
+ end
89
+
90
+ top_level_js = nil
91
+
92
+ add_dep = nil
93
+
94
+ clear_deps = lambda do |w|
95
+ begin
96
+ if db.call
97
+ loc = w
98
+ begin loc = w.location; rescue; end
99
+ loc && ( loc = loc.to_s )
100
+ if ( loc !~ %r((http?s|file|about):) )
101
+ begin
102
+ loc = "file://" + Pathname(loc).realpath.to_s
103
+ rescue Errno::ENOENT; end
104
+ end
105
+ # $stderr.puts "clear", loc
106
+ if loc and loc != "about:blank"
107
+ paths = db.call[loc+".on.yml"] || []
108
+ paths.each do |path|
109
+ # $stderr.print "#{path} not by #{loc}\n";
110
+ db.call[path+".by.yml"].delete loc
111
+ end
112
+ # $stderr.print "#{loc} not on anything\n";
113
+ db.call.delete loc+".on.yml"
114
+ end
115
+ end
116
+ add_dep.call( nil, loc )
117
+ rescue Exception => e; $stderr.puts e, e.class; $stderr.puts e.backtrace; end
118
+ end
119
+
120
+ if $envjsrb_deps
121
+ Envjs::Net::File.on_open = clear_deps
122
+ end
123
+
124
+ add_dep = lambda do |w, f|
125
+ if db.call
126
+ loc = nil
127
+ begin loc = w.location; rescue Exception; end
128
+ loc && ( loc = loc.to_s )
129
+ if ( loc && loc !~ %r((http?s|file|about):) )
130
+ loc = "file://" + Pathname(loc).realpath.to_s
131
+ end
132
+ path = f
133
+ if ( path !~ %r((http?s|file|about):) )
134
+ begin
135
+ path = "file://" + Pathname(path).realpath.to_s
136
+ rescue Errno::ENOENT
137
+ return
138
+ end
139
+ end
140
+ if !loc || loc == "about:blank"
141
+ uri = URI.parse top_level_js
142
+ if uri.scheme == nil
143
+ uri.scheme = "file"
144
+ begin
145
+ uri.path = Pathname.new(uri.path).realpath.to_s
146
+ rescue Errno::ENOENT; end
147
+ uri = URI.parse uri.to_s
148
+ end
149
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
150
+
151
+ # tll = "file://" + Pathname(top_level_js).realpath.to_s
152
+
153
+ tll = uri_s
154
+
155
+ if ( tll != path )
156
+ loc = tll
157
+ end
158
+ end
159
+ if loc and loc != "about:blank"
160
+ on = db.call[loc+".on.yml"] || []
161
+ on << path
162
+ on.uniq!
163
+ db.call[loc+".on.yml"] = on
164
+ by = db.call[path+".by.yml"] || []
165
+ by << loc
166
+ by.uniq!
167
+ db.call[path+".by.yml"] = by
168
+ # $stderr.print "#{loc} on #{path}: #{db.call[loc+'.on.yml'].join(' ')}\n"
169
+ # $stderr.print "#{path} by #{loc}: #{db.call[path+'.by.yml'].join(' ')}\n"
170
+ end
171
+ end
172
+ end
173
+
174
+ (class << self; self; end).send :define_method, :top_level_load do |path|
175
+ # $stderr.print "tll #{path}\n"
176
+ top_level_js = path
177
+ clear_deps.call( path )
178
+ end
179
+
180
+ master.load = lambda { |*files|
181
+ if files.length == 2 && !(String === files[1])
182
+ f = files[0]
183
+ w = files[1]
184
+
185
+ # Hmmm ...
186
+ uri = URI.parse f
187
+
188
+ if uri.scheme == nil
189
+ uri.scheme = "file"
190
+ begin
191
+ uri.path = Pathname.new(uri.path).realpath.to_s
192
+ rescue Errno::ENOENT; end
193
+ uri = URI.parse uri.to_s
194
+ end
195
+
196
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
197
+
198
+ if uri.scheme == "file"
199
+ uri_s = uri.path
200
+ elsif uri.scheme == "data"
201
+ raise "implement 0"
202
+ end
203
+
204
+ v = open(uri_s).read.gsub(/\A#!.*$/, '')
205
+ loc = nil
206
+ add_dep.call w, f
207
+ evaluate(v, f, 1, w, w, f)
208
+ else
209
+ load *files
210
+ end
211
+ }
212
+
213
+ def load *files
214
+ files.map { |f|
215
+ # Hmmm ...
216
+
217
+ uri = URI.parse f
218
+ if uri.scheme == nil
219
+ uri.scheme = "file"
220
+ begin
221
+ uri.path = Pathname.new(uri.path).realpath.to_s
222
+ rescue Errno::ENOENT; end
223
+ uri = URI.parse uri.to_s
224
+ end
225
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
226
+
227
+ if uri.scheme == "file"
228
+ super uri.path
229
+ elsif uri.scheme == "data"
230
+ raise "implement 1"
231
+ else
232
+ raise "hell 1"
233
+ end
234
+
235
+ # v = open(uri_s).read.gsub(/\A#!.*$/, '')
236
+ # loc = nil
237
+ # add_dep.call w, f
238
+ # evaluate(v, f, 1, w, w, f)
239
+ # evaluate(File.read(f).gsub(/\A#!.*$/, ''), f, 1)
240
+
241
+ }.last
242
+ end
243
+
244
+ master.reload = lambda { |*files|
245
+ if files.length == 2 && !(String === files[1])
246
+ f = files[0]
247
+ w = files[1]
248
+ v = open(f).read.gsub(/\A#!.*$/, '')
249
+ loc = nil
250
+ add_dep.call w, f
251
+ reevaluate(v, f, 1, w, w, f)
252
+ else
253
+ reload *files
254
+ end
255
+ }
256
+
257
+ master.evaluate = lambda { |v,w|
258
+ evaluate(v,"inline",1,w,w);
259
+ }
260
+
261
+ master.new_split_global_outer = lambda { new_split_global_outer }
262
+ master.new_split_global_inner = lambda { |outer,_| new_split_global_inner outer }
263
+
264
+ # create an proto window object and proxy
265
+
266
+ outer = new_split_global_outer
267
+ window = inner = new_split_global_inner( outer )
268
+
269
+ master.symbols.each do |symbol|
270
+ window[symbol] = master[symbol]
271
+ end
272
+
273
+ master.first_script_window = window
274
+
275
+ window["$master"] = master
276
+ window["$options"] = evaluate("new Object");
277
+ window["$options"].proxy = outer
278
+
279
+ window.evaluate = lambda { |s|
280
+ return master.evaluate.call(s,window);
281
+ }
282
+
283
+ window.load = lambda { |*files|
284
+ files.each do |f|
285
+ master.load.call f, window
286
+ end
287
+ }
288
+
289
+ window.reload = lambda { |*files|
290
+ files.each do |f|
291
+ master.reload.call f, window
292
+ end
293
+ }
294
+
295
+ ( class << self; self; end ).send :define_method, :wait do
296
+ master["finalize"] && master.finalize.call
297
+ master.timers && master.timers.wait
298
+ end
299
+
300
+ scripts = {}
301
+
302
+ ( class << self; self; end ).send :define_method, :become_first_script_window do
303
+ # p "heh", inner, master.first_script_window
304
+ inner = master.first_script_window
305
+ end
306
+
307
+ ( class << self; self; end ).send :define_method, :evaluate do |*args|
308
+ ( script, file, line, global, scope, fn ) = *args
309
+ # print "eval in " + script[0,50].inspect + (scope ? scope.toString() : "nil") + "\n"
310
+ global = nil
311
+ scope ||= inner
312
+ if fn
313
+ compiled_script = scripts[fn]
314
+ end
315
+ # compiled_script = compile(script, file, line, global)
316
+ compiled_script ||= compile(script, file, line, global)
317
+ if fn && !scripts[fn]
318
+ scripts[fn] = compiled_script
319
+ end
320
+ # p "?", script
321
+ evaluate_compiled_script(compiled_script,scope)
322
+ end
323
+
324
+ ( class << self; self; end ).send :define_method, :reevaluate do |*args|
325
+ ( script, file, line, global, scope, fn ) = *args
326
+ # print "eval in " + script[0,50].inspect + (scope ? scope.toString() : "nil") + "\n"
327
+ global = nil
328
+ scope ||= inner
329
+ compiled_script = compile(script, file, line, global)
330
+ if fn
331
+ scripts[fn] = compiled_script
332
+ end
333
+ evaluate_compiled_script(compiled_script,scope)
334
+ end
335
+
336
+ @envjs = inner
337
+
338
+ ( class << self; self; end ).send :define_method, :"[]" do |key|
339
+ key == "this" && evaluate("this") || @envjs[key]
340
+ end
341
+
342
+ ( class << self; self; end ).send :define_method, :"[]=" do |k,v|
343
+ @envjs[k] = v
344
+ end
345
+
346
+ load Envjs::ENVJS
347
+
348
+ end
349
+ end
350
+
351
+ end