uglifier 1.3.0 → 4.2.1

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.
data/README.md CHANGED
@@ -1,6 +1,25 @@
1
- # Uglifier [![Build Status](https://secure.travis-ci.org/lautis/uglifier.png?branch=master)](http://travis-ci.org/lautis/uglifier) [![Dependency Status](https://gemnasium.com/lautis/uglifier.png?travis)](https://gemnasium.com/lautis/uglifier)
1
+ # Uglifier
2
2
 
3
- Ruby wrapper for [UglifyJS](https://github.com/mishoo/UglifyJS) JavaScript compressor.
3
+ Ruby wrapper for [UglifyJS](https://github.com/mishoo/UglifyJS2) JavaScript
4
+ compressor.
5
+
6
+ UglifyJS only works with ES5. If you need to compress ES6, [ruby-terser](https://github.com/ahorek/terser-ruby) is a better option.
7
+
8
+ ### Rails
9
+
10
+ When used in Rails, replace
11
+
12
+ ```ruby
13
+ config.assets.js_compressor = :uglifier
14
+ ```
15
+
16
+ with
17
+
18
+ ```ruby
19
+ config.assets.js_compressor = Uglifier.new(harmony: true)
20
+ ```
21
+
22
+ in `config/environments/production.rb`.
4
23
 
5
24
  ## Installation
6
25
 
@@ -8,71 +27,152 @@ Uglifier is available as a ruby gem.
8
27
 
9
28
  $ gem install uglifier
10
29
 
11
- Ensure that your environment has a JavaScript interpreter supported by [ExecJS](https://github.com/sstephenson/execjs). Installing `therubyracer` gem is a safe choice and having `node` in `PATH` works too.
30
+ Ensure that your environment has a JavaScript interpreter supported by
31
+ [ExecJS](https://github.com/rails/execjs). Using `therubyracer` gem
32
+ is a safe choice if a runtime isn't already present. Note that while JScript built-in Windows 7 and older works, it is extremely slow.
12
33
 
13
34
  ## Usage
14
35
 
15
- require 'uglifier'
36
+ ```ruby
37
+ require 'uglifier'
16
38
 
17
- Uglifier.new.compile(File.read("source.js"))
18
- # => js file minified
39
+ Uglifier.new.compile(File.read("source.js"))
40
+ # => js file minified
19
41
 
20
- # Or alternatively
21
- Uglifier.compile(File.read("source.js"))
42
+ # Or alternatively
43
+ Uglifier.compile(File.read("source.js"))
44
+ ```
22
45
 
23
- When initializing UglifyJS, you can tune the behavior of UglifyJS by passing options. For example, if you want top-level variable names to be mangled:
46
+ Uglifier also supports generating source maps:
24
47
 
25
- Uglifier.new(:toplevel => true).compile(source)
48
+ ```ruby
49
+ uglified, source_map = Uglifier.new.compile_with_map(source)
50
+ ```
26
51
 
27
- # Or
28
- Uglifier.compile(source, :toplevel => true)
52
+ When initializing UglifyJS, you can tune the behavior of UglifyJS by passing options. For example, if you want disable variable name mangling:
29
53
 
30
- Available options and their defaults are
31
-
32
- {
33
- :mangle => true, # Mangle variable and function names, use :variables to skip function mangling
34
- :toplevel => false, # Mangle top-level variable names
35
- :except => [], # Variable names to be excluded from mangling
36
- :max_line_length => 32 * 1024, # Maximum line length
37
- :squeeze => true, # Squeeze code resulting in smaller, but less-readable code
38
- :seqs => true, # Reduce consecutive statements in blocks into single statement
39
- :dead_code => true, # Remove dead code (e.g. after return)
40
- :lift_vars => false, # Lift all var declarations at the start of the scope
41
- :unsafe => false, # Optimizations known to be unsafe in some situations
42
- :copyright => true, # Show copyright message
43
- :ascii_only => false, # Encode non-ASCII characters as Unicode code points
44
- :inline_script => false, # Escape </script
45
- :quote_keys => false, # Quote keys in object literals
46
- :define => {}, # Define values for symbol replacement
47
- :beautify => false, # Ouput indented code
48
- :beautify_options => {
49
- :indent_level => 4,
50
- :indent_start => 0,
51
- :space_colon => false
52
- }
53
- }
54
-
55
- ## Development
54
+ ```ruby
55
+ Uglifier.new(:mangle => false).compile(source)
56
56
 
57
- Uglifier uses [stitch](https://github.com/sstephenson/stitch) to compile UglifyJs for non-node JS runtimes. If you need to update or patch UglifyJS, you can stitch UglifyJS using
57
+ # Or
58
+ Uglifier.compile(source, :mangle => false)
59
+ ```
58
60
 
59
- node build.js
61
+ Available options and their defaults are
60
62
 
61
- ## Submitting an issue
63
+ ```ruby
64
+ {
65
+ :output => {
66
+ :ascii_only => true, # Escape non-ASCII characters
67
+ :comments => :copyright, # Preserve comments (:all, :jsdoc, :copyright, :none, Regexp (see below))
68
+ :inline_script => false, # Escape occurrences of </script in strings
69
+ :quote_keys => false, # Quote keys in object literals
70
+ :max_line_len => 32 * 1024, # Maximum line length in minified code
71
+ :bracketize => false, # Bracketize if, for, do, while or with statements, even if their body is a single statement
72
+ :semicolons => true, # Separate statements with semicolons
73
+ :preserve_line => false, # Preserve line numbers in outputs
74
+ :beautify => false, # Beautify output
75
+ :indent_level => 4, # Indent level in spaces
76
+ :indent_start => 0, # Starting indent level
77
+ :width => 80, # Specify line width when beautifier is used (only with beautifier)
78
+ :preamble => nil, # Preamble for the generated JS file. Can be used to insert any code or comment.
79
+ :wrap_iife => false, # Wrap IIFEs in parenthesis. Note: this disables the negate_iife compression option.
80
+ :shebang => true, # Preserve shebang (#!) in preamble (shell scripts)
81
+ :quote_style => 0, # Quote style, possible values :auto (default), :single, :double, :original
82
+ :keep_quoted_props => false # Keep quotes property names
83
+ },
84
+ :mangle => {
85
+ :eval => false, # Mangle names when eval of when is used in scope
86
+ :reserved => ["$super"], # Argument names to be excluded from mangling
87
+ :sort => false, # Assign shorter names to most frequently used variables. Often results in bigger output after gzip.
88
+ :toplevel => false, # Mangle names declared in the toplevel scope
89
+ :properties => false, # Mangle property names
90
+ :keep_fnames => false # Do not modify function names
91
+ }, # Mangle variable and function names, set to false to skip mangling
92
+ :mangle_properties => {
93
+ :regex => nil, # A regular expression to filter property names to be mangled
94
+ :ignore_quoted => false, # Only mangle unquoted property names
95
+ :debug => false, # Mangle names with the original name still present
96
+ }, # Mangle property names, disabled by default
97
+ :compress => {
98
+ :sequences => true, # Allow statements to be joined by commas
99
+ :properties => true, # Rewrite property access using the dot notation
100
+ :dead_code => true, # Remove unreachable code
101
+ :drop_debugger => true, # Remove debugger; statements
102
+ :unsafe => false, # Apply "unsafe" transformations
103
+ :unsafe_comps => false, # Reverse < and <= to > and >= to allow improved compression. This might be unsafe when an at least one of two operands is an object with computed values due the use of methods like get, or valueOf. This could cause change in execution order after operands in the comparison are switching. Compression only works if both comparisons and unsafe_comps are both set to true.
104
+ :unsafe_math => false, # Optimize numerical expressions like 2 * x * 3 into 6 * x, which may give imprecise floating point results.
105
+ :unsafe_proto => false, # Optimize expressions like Array.prototype.slice.call(a) into [].slice.call(a)
106
+ :conditionals => true, # Optimize for if-s and conditional expressions
107
+ :comparisons => true, # Apply binary node optimizations for comparisons
108
+ :evaluate => true, # Attempt to evaluate constant expressions
109
+ :booleans => true, # Various optimizations to boolean contexts
110
+ :loops => true, # Optimize loops when condition can be statically determined
111
+ :unused => true, # Drop unreferenced functions and variables
112
+ :toplevel => false, # Drop unreferenced top-level functions and variables
113
+ :top_retain => [], # prevent specific toplevel functions and variables from `unused` removal
114
+ :hoist_funs => true, # Hoist function declarations
115
+ :hoist_vars => false, # Hoist var declarations
116
+ :if_return => true, # Optimizations for if/return and if/continue
117
+ :join_vars => true, # Join consecutive var statements
118
+ :collapse_vars => false, # Collapse single-use var and const definitions when possible.
119
+ :reduce_funcs => false, # Inline single-use functions as function expressions. Depends on reduce_vars.
120
+ :reduce_vars => false, # Collapse variables assigned with and used as constant values.
121
+ :negate_iife => true, # Negate immediately invoked function expressions to avoid extra parens
122
+ :pure_getters => false, # Assume that object property access does not have any side-effects
123
+ :pure_funcs => nil, # List of functions without side-effects. Can safely discard function calls when the result value is not used
124
+ :drop_console => false, # Drop calls to console.* functions
125
+ :keep_fargs => false, # Preserve unused function arguments
126
+ :keep_fnames => false, # Do not drop names in function definitions
127
+ :passes => 1, # Number of times to run compress. Raising the number of passes will increase compress time, but can produce slightly smaller code.
128
+ :keep_infinity => false, # Prevent compression of Infinity to 1/0
129
+ :side_effects => true, # Pass false to disable potentially dropping functions marked as "pure" using pure comment annotation. See UglifyJS documentation for details.
130
+ :switches => true, # de-duplicate and remove unreachable switch branches
131
+ }, # Apply transformations to code, set to false to skip
132
+ :parse => {
133
+ :bare_returns => false, # Allow top-level return statements.
134
+ :expression => false, # Parse a single expression, rather than a program (for parsing JSON).
135
+ :html5_comments => true, # Ignore HTML5 comments in input
136
+ :shebang => true, # support #!command as the first line
137
+ :strict => false
138
+ },
139
+ :define => {}, # Define values for symbol replacement
140
+ :enclose => false, # Enclose in output function wrapper, define replacements as key-value pairs
141
+ :keep_fnames => false, # Generate code safe for the poor souls relying on Function.prototype.name at run-time. Sets both compress and mangle keep_fanems to true.
142
+ :source_map => {
143
+ :map_url => false, # Url for source mapping to be appended in minified source
144
+ :url => false, # Url for original source to be appended in minified source
145
+ :sources_content => false, # Include original source content in map
146
+ :filename => nil, # The filename of the input file
147
+ :root => nil, # The URL of the directory which contains :filename
148
+ :output_filename => nil, # The filename or URL where the minified output can be found
149
+ :input_source_map => nil # The contents of the source map describing the input
150
+ },
151
+ :error_context_lines => 8, # How many context lines surrounding the error line. Env var ERROR_CONTEXT_LINES overrides this option
152
+ :harmony => false # Enable ES6/Harmony mode (experimental). Disabling mangling and compressing is recommended with Harmony mode.
153
+ }
154
+ ```
155
+
156
+ When passing a regular expression to the output => comments option, be sure to pass a valid Ruby Regexp.
157
+ The beginning and ending of comments are removed and cannot be matched (/*, */, //). For example:
158
+ When matching
159
+
160
+ ```
161
+ /*!
162
+ * comment
163
+ */
164
+ ```
165
+
166
+ use `Uglifier.new(output: {comments: /^!/})`.
62
167
 
63
- Uglifier uses the [GitHub issue tracker](https://github.com/lautis/uglifier/issues) to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. You can indicate support for an existing issuse by voting it up. When submitting a bug report, please include a Gist that includes a stack trace and any details that may be necessary to reproduce the bug, including your gem version, Ruby version, **MultiJSON engine** and **ExecJS runtime**. Ideally, a bug report should include a pull request with failing specs.
168
+ ## Development
64
169
 
65
- ## Contributing to uglifier
170
+ Tests are run using
66
171
 
67
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
68
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
69
- * Fork the project
70
- * Start a feature/bugfix branch
71
- * Commit and push until you are happy with your contribution
72
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
73
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
172
+ bundle exec rake
74
173
 
174
+ See [CONTRIBUTING](https://github.com/lautis/uglifier/blob/master/CONTRIBUTING.md) for details about working on and contributing to Uglifier.
75
175
 
76
176
  ## Copyright
77
177
 
78
- © Ville Lautanala, [Flowdock](https://flowdock.com/). Released under MIT license, see [LICENSE.txt](https://github.com/lautis/uglifier/blob/master/LICENSE.txt) for more details.
178
+ © Ville Lautanala. Released under MIT license, see [LICENSE](https://github.com/lautis/uglifier/blob/master/LICENSE.txt) for details.
data/Rakefile CHANGED
@@ -1,39 +1,137 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "uglifier"
16
- gem.summary = %Q{Ruby wrapper for UglifyJS JavaScript compressor}
17
- gem.email = "lautis@gmail.com"
18
- gem.homepage = "http://github.com/lautis/uglifier"
19
- gem.authors = ["Ville Lautanala"]
20
- end
21
- Jeweler::RubygemsDotOrgTasks.new
22
-
23
- require 'rspec/core'
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'bundler/gem_tasks'
24
5
  require 'rspec/core/rake_task'
25
6
  RSpec::Core::RakeTask.new(:spec) do |spec|
26
7
  spec.pattern = FileList['spec/**/*_spec.rb']
27
8
  end
28
9
 
29
- task :default => :spec
10
+ def version
11
+ ENV.fetch('VERSION')
12
+ end
13
+
14
+ HEADER = "## next"
15
+
16
+ def changelog_tail
17
+ changelog = File.read("CHANGELOG.md")
18
+ if changelog.start_with?(HEADER)
19
+ changelog[HEADER.length + 2..-1]
20
+ else
21
+ "\n" + changelog
22
+ end
23
+ end
24
+
25
+ def compare_url(from, to)
26
+ "https://github.com/mishoo/UglifyJS2/compare/#{from}...#{to}"
27
+ end
28
+
29
+ def previous_version
30
+ match = File.read("CHANGELOG.md").scan(/- update UglifyJS to \[(.*)\]\(/)
31
+ match ? match[0][0].chomp : nil
32
+ end
33
+
34
+ def git_commit(files, message)
35
+ `git add #{files.join(' ')}`
36
+ `git commit -S -m "#{message.gsub('"', "\\\"")}"`
37
+ end
38
+
39
+ # rubocop:disable Metrics/BlockLength
40
+ namespace :uglifyjs do
41
+ desc "Update UglifyJS source to version specified in VERSION environment variable"
42
+ task :update do
43
+ cd 'vendor/uglifyjs' do
44
+ `git fetch && git checkout v#{version}`
45
+ end
46
+ end
47
+
48
+ desc "Rebuild lib/uglify*.js"
49
+ task :build do
50
+ cd 'vendor/source-map/' do
51
+ `npm install --no-package-lock --no-save`
52
+ end
53
+
54
+ cd 'vendor/uglifyjs/' do
55
+ # required to run ./uglifyjs2 --self; not bundled.
56
+ `npm install --no-package-lock --no-save`
57
+ end
58
+
59
+ cd 'vendor/uglifyjs-harmony' do
60
+ # required to run ./uglifyjs2 --self; not bundled.
61
+ `npm install --no-package-lock --no-save`
62
+ end
63
+
64
+ FileUtils.cp("vendor/source-map/dist/source-map.js", "lib/source-map.js")
65
+
66
+ source = `./vendor/uglifyjs/bin/uglifyjs --self --comments /Copyright/`
67
+ File.write("lib/uglify.js", source)
68
+
69
+ harmony_source = `./vendor/uglifyjs-harmony/bin/uglifyjs --self --comments /Copyright/`
70
+ File.write("lib/uglify-harmony.js", harmony_source)
71
+
72
+ FileUtils.cp("vendor/split/split.js", "lib/split.js")
73
+ `patch -p1 -i patches/es5-string-split.patch`
74
+ end
75
+
76
+ desc "Add UglifyJS version bump to changelog"
77
+ task :changelog do
78
+ url = compare_url("v#{previous_version}", "v#{version}")
79
+ item = "- update UglifyJS to [#{version}](#{url})"
80
+ changelog = "#{HEADER}\n\n#{item}\n#{changelog_tail}"
81
+ File.write("CHANGELOG.md", changelog)
82
+ end
83
+
84
+ desc "Commit changes from UglifyJS version bump"
85
+ task :commit do
86
+ files = [
87
+ 'CHANGELOG.md',
88
+ 'lib/uglify.js',
89
+ 'lib/uglify-harmony.js',
90
+ 'vendor/uglifyjs',
91
+ 'vendor/uglifyjs-harmony'
92
+ ]
93
+ git_commit(files, "Update UglifyJS to #{version}")
94
+ end
95
+ end
96
+ # rubocop:enable Metrics/BlockLength
97
+
98
+ desc "Update UglifyJS to version specified in VERSION environment variable"
99
+ task :uglifyjs => ['uglifyjs:update', 'uglifyjs:build', 'uglifyjs:changelog', 'uglifyjs:commit']
100
+
101
+ namespace :version do
102
+ desc "Write version to CHANGELOG.md"
103
+ task :changelog do
104
+ content = File.read("CHANGELOG.md")
105
+ date = Time.now.strftime("%d %B %Y")
106
+ File.write("CHANGELOG.md", content.gsub("## next", "## #{version} (#{date})"))
107
+ end
30
108
 
31
- require 'rdoc/task'
32
- Rake::RDocTask.new do |rdoc|
33
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
109
+ desc "Write version to uglifier.rb"
110
+ task :ruby do
111
+ file = "lib/uglifier/version.rb"
112
+ content = File.read("lib/uglifier/version.rb")
113
+ File.write(file, content.gsub(/VERSION = "(.*)"/, "VERSION = \"#{version}\""))
114
+ end
34
115
 
35
- rdoc.rdoc_dir = 'rdoc'
36
- rdoc.title = "uglifier #{version}"
37
- rdoc.rdoc_files.include('README*')
38
- rdoc.rdoc_files.include('lib/**/*.rb')
116
+ desc "Commit changes from Uglifier version bump"
117
+ task :commit do
118
+ files = ["CHANGELOG.md", "lib/uglifier/version.rb"]
119
+ git_commit(files, "Bump version to #{version}")
120
+ end
121
+
122
+ desc "Create git tag for version"
123
+ task :tag do
124
+ `git tag -s -m "Version #{version}" v#{version}`
125
+ end
126
+ end
127
+
128
+ desc "Update Uglifier to version specified in VERSION environment variable"
129
+ task :version => ['version:changelog', 'version:ruby', 'version:commit', 'version:tag']
130
+
131
+ begin
132
+ require 'rubocop/rake_task'
133
+ RuboCop::RakeTask.new(:rubocop)
134
+ task :default => [:rubocop, :spec]
135
+ rescue LoadError
136
+ task :default => [:spec]
39
137
  end
data/lib/es5.js CHANGED
@@ -185,3 +185,137 @@ if (!Array.prototype.indexOf) {
185
185
  return -1;
186
186
  }
187
187
  }
188
+
189
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Object/keys
190
+ if (!Object.keys) {
191
+ Object.keys = (function () {
192
+ var hasOwnProperty = Object.prototype.hasOwnProperty,
193
+ hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
194
+ dontEnums = [
195
+ 'toString',
196
+ 'toLocaleString',
197
+ 'valueOf',
198
+ 'hasOwnProperty',
199
+ 'isPrototypeOf',
200
+ 'propertyIsEnumerable',
201
+ 'constructor'
202
+ ],
203
+ dontEnumsLength = dontEnums.length;
204
+
205
+ return function (obj) {
206
+ if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
207
+
208
+ var result = [];
209
+
210
+ for (var prop in obj) {
211
+ if (hasOwnProperty.call(obj, prop)) result.push(prop);
212
+ }
213
+
214
+ if (hasDontEnumBug) {
215
+ for (var i=0; i < dontEnumsLength; i++) {
216
+ if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
217
+ }
218
+ }
219
+ return result;
220
+ }
221
+ })()
222
+ };
223
+
224
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Object/create
225
+ if (!Object.create) {
226
+ Object.create = function (o) {
227
+ if (arguments.length > 1) {
228
+ throw new Error('Object.create implementation only accepts the first parameter.');
229
+ }
230
+ function F() {}
231
+ F.prototype = o;
232
+ return new F();
233
+ };
234
+ }
235
+
236
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Array/filter
237
+ if (!Array.prototype.filter)
238
+ {
239
+ Array.prototype.filter = function(fun /*, thisp*/)
240
+ {
241
+ "use strict";
242
+
243
+ if (this == null)
244
+ throw new TypeError();
245
+
246
+ var t = Object(this);
247
+ var len = t.length >>> 0;
248
+ if (typeof fun != "function")
249
+ throw new TypeError();
250
+
251
+ var res = [];
252
+ var thisp = arguments[1];
253
+ for (var i = 0; i < len; i++)
254
+ {
255
+ if (i in t)
256
+ {
257
+ var val = t[i]; // in case fun mutates this
258
+ if (fun.call(thisp, val, i, t))
259
+ res.push(val);
260
+ }
261
+ }
262
+
263
+ return res;
264
+ };
265
+ }
266
+
267
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind
268
+ if (!Function.prototype.bind) {
269
+ Function.prototype.bind = function (oThis) {
270
+ if (typeof this !== "function") {
271
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
272
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
273
+ }
274
+
275
+ var aArgs = Array.prototype.slice.call(arguments, 1),
276
+ fToBind = this,
277
+ fNOP = function () {},
278
+ fBound = function () {
279
+ return fToBind.apply(this instanceof fNOP && oThis
280
+ ? this
281
+ : oThis,
282
+ aArgs.concat(Array.prototype.slice.call(arguments)));
283
+ };
284
+
285
+ fNOP.prototype = this.prototype;
286
+ fBound.prototype = new fNOP();
287
+
288
+ return fBound;
289
+ };
290
+ }
291
+
292
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Array/isArray
293
+ if(!Array.isArray) {
294
+ Array.isArray = function (vArg) {
295
+ return Object.prototype.toString.call(vArg) === "[object Array]";
296
+ };
297
+ }
298
+
299
+ // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/trim
300
+ if(!String.prototype.trim) {
301
+ String.prototype.trim = function () {
302
+ return this.replace(/^\s+|\s+$/g,'');
303
+ };
304
+ }
305
+
306
+
307
+ function definePropertyWorks() {
308
+ try {
309
+ Object.defineProperty({}, "property", {});
310
+ return true;
311
+ } catch (exception) {
312
+ return false;
313
+ }
314
+ }
315
+
316
+ if (!definePropertyWorks()) {
317
+ Object.defineProperty = function defineProperty(object) {
318
+ // fail silently
319
+ return object;
320
+ }
321
+ }