Test - CF per XBOX
This commit is contained in:
@@ -1 +0,0 @@
|
||||
__author__ = 'Piotr Dabkowski'
|
||||
@@ -1,48 +0,0 @@
|
||||
from ..base import *
|
||||
|
||||
|
||||
@Js
|
||||
def Array():
|
||||
if len(arguments) == 0 or len(arguments) > 1:
|
||||
return arguments.to_list()
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber):
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js([])
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
return [a]
|
||||
|
||||
|
||||
Array.create = Array
|
||||
Array.own['length']['value'] = Js(1)
|
||||
|
||||
|
||||
@Js
|
||||
def isArray(arg):
|
||||
return arg.Class == 'Array'
|
||||
|
||||
|
||||
Array.define_own_property('isArray', {
|
||||
'value': isArray,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
ArrayPrototype.define_own_property('constructor', {
|
||||
'value': Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
@@ -1,41 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
# todo check everything :)
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def ArrayBuffer():
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber):
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(bytearray([0] * length))
|
||||
return temp
|
||||
return Js(bytearray([0]))
|
||||
|
||||
|
||||
ArrayBuffer.create = ArrayBuffer
|
||||
ArrayBuffer.own['length']['value'] = Js(None)
|
||||
|
||||
ArrayBuffer.define_own_property(
|
||||
'prototype', {
|
||||
'value': ArrayBufferPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
ArrayBufferPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': ArrayBuffer,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': True
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
from ..base import *
|
||||
|
||||
BooleanPrototype.define_own_property('constructor', {
|
||||
'value': Boolean,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Boolean.define_own_property(
|
||||
'prototype', {
|
||||
'value': BooleanPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,405 +0,0 @@
|
||||
from ..base import *
|
||||
from .time_helpers import *
|
||||
|
||||
TZ_OFFSET = (time.altzone // 3600)
|
||||
ABS_OFFSET = abs(TZ_OFFSET)
|
||||
TZ_NAME = time.tzname[1]
|
||||
ISO_FORMAT = '%s-%s-%sT%s:%s:%s.%sZ'
|
||||
|
||||
|
||||
@Js
|
||||
def Date(year, month, date, hours, minutes, seconds, ms):
|
||||
return now().to_string()
|
||||
|
||||
|
||||
Date.Class = 'Date'
|
||||
|
||||
|
||||
def now():
|
||||
return PyJsDate(int(time.time() * 1000), prototype=DatePrototype)
|
||||
|
||||
|
||||
@Js
|
||||
def UTC(year, month, date, hours, minutes, seconds, ms): # todo complete this
|
||||
args = arguments
|
||||
y = args[0].to_number()
|
||||
m = args[1].to_number()
|
||||
l = len(args)
|
||||
dt = args[2].to_number() if l > 2 else Js(1)
|
||||
h = args[3].to_number() if l > 3 else Js(0)
|
||||
mi = args[4].to_number() if l > 4 else Js(0)
|
||||
sec = args[5].to_number() if l > 5 else Js(0)
|
||||
mili = args[6].to_number() if l > 6 else Js(0)
|
||||
if not y.is_nan() and 0 <= y.value <= 99:
|
||||
y = y + Js(1900)
|
||||
t = TimeClip(MakeDate(MakeDay(y, m, dt), MakeTime(h, mi, sec, mili)))
|
||||
return PyJsDate(t, prototype=DatePrototype)
|
||||
|
||||
|
||||
@Js
|
||||
def parse(string):
|
||||
return PyJsDate(
|
||||
TimeClip(parse_date(string.to_string().value)),
|
||||
prototype=DatePrototype)
|
||||
|
||||
|
||||
Date.define_own_property('now', {
|
||||
'value': Js(now),
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Date.define_own_property('parse', {
|
||||
'value': parse,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Date.define_own_property('UTC', {
|
||||
'value': UTC,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
|
||||
class PyJsDate(PyJs):
|
||||
Class = 'Date'
|
||||
extensible = True
|
||||
|
||||
def __init__(self, value, prototype=None):
|
||||
self.value = value
|
||||
self.own = {}
|
||||
self.prototype = prototype
|
||||
|
||||
# todo fix this problematic datetime part
|
||||
def to_local_dt(self):
|
||||
return datetime.datetime.utcfromtimestamp(
|
||||
UTCToLocal(self.value) // 1000)
|
||||
|
||||
def to_utc_dt(self):
|
||||
return datetime.datetime.utcfromtimestamp(self.value // 1000)
|
||||
|
||||
def local_strftime(self, pattern):
|
||||
if self.value is NaN:
|
||||
return 'Invalid Date'
|
||||
try:
|
||||
dt = self.to_local_dt()
|
||||
except:
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'unsupported date range. Will fix in future versions')
|
||||
try:
|
||||
return dt.strftime(pattern)
|
||||
except:
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Could not generate date string from this date (limitations of python.datetime)'
|
||||
)
|
||||
|
||||
def utc_strftime(self, pattern):
|
||||
if self.value is NaN:
|
||||
return 'Invalid Date'
|
||||
try:
|
||||
dt = self.to_utc_dt()
|
||||
except:
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'unsupported date range. Will fix in future versions')
|
||||
try:
|
||||
return dt.strftime(pattern)
|
||||
except:
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Could not generate date string from this date (limitations of python.datetime)'
|
||||
)
|
||||
|
||||
|
||||
def parse_date(py_string): # todo support all date string formats
|
||||
try:
|
||||
try:
|
||||
dt = datetime.datetime.strptime(py_string, "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
except:
|
||||
dt = datetime.datetime.strptime(py_string, "%Y-%m-%dT%H:%M:%SZ")
|
||||
return MakeDate(
|
||||
MakeDay(Js(dt.year), Js(dt.month - 1), Js(dt.day)),
|
||||
MakeTime(
|
||||
Js(dt.hour), Js(dt.minute), Js(dt.second),
|
||||
Js(dt.microsecond // 1000)))
|
||||
except:
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Could not parse date %s - unsupported date format. Currently only supported format is RFC3339 utc. Sorry!'
|
||||
% py_string)
|
||||
|
||||
|
||||
def date_constructor(*args):
|
||||
if len(args) >= 2:
|
||||
return date_constructor2(*args)
|
||||
elif len(args) == 1:
|
||||
return date_constructor1(args[0])
|
||||
else:
|
||||
return date_constructor0()
|
||||
|
||||
|
||||
def date_constructor0():
|
||||
return now()
|
||||
|
||||
|
||||
def date_constructor1(value):
|
||||
v = value.to_primitive()
|
||||
if v._type() == 'String':
|
||||
v = parse_date(v.value)
|
||||
else:
|
||||
v = v.to_int()
|
||||
return PyJsDate(TimeClip(v), prototype=DatePrototype)
|
||||
|
||||
|
||||
def date_constructor2(*args):
|
||||
y = args[0].to_number()
|
||||
m = args[1].to_number()
|
||||
l = len(args)
|
||||
dt = args[2].to_number() if l > 2 else Js(1)
|
||||
h = args[3].to_number() if l > 3 else Js(0)
|
||||
mi = args[4].to_number() if l > 4 else Js(0)
|
||||
sec = args[5].to_number() if l > 5 else Js(0)
|
||||
mili = args[6].to_number() if l > 6 else Js(0)
|
||||
if not y.is_nan() and 0 <= y.value <= 99:
|
||||
y = y + Js(1900)
|
||||
t = TimeClip(
|
||||
LocalToUTC(MakeDate(MakeDay(y, m, dt), MakeTime(h, mi, sec, mili))))
|
||||
return PyJsDate(t, prototype=DatePrototype)
|
||||
|
||||
|
||||
Date.create = date_constructor
|
||||
|
||||
DatePrototype = PyJsDate(float('nan'), prototype=ObjectPrototype)
|
||||
|
||||
|
||||
def check_date(obj):
|
||||
if obj.Class != 'Date':
|
||||
raise MakeError('TypeError', 'this is not a Date object')
|
||||
|
||||
|
||||
class DateProto:
|
||||
def toString():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return 'Invalid Date'
|
||||
offset = (UTCToLocal(this.value) - this.value) // msPerHour
|
||||
return this.local_strftime(
|
||||
'%a %b %d %Y %H:%M:%S GMT') + '%s00 (%s)' % (pad(
|
||||
offset, 2, True), GetTimeZoneName(this.value))
|
||||
|
||||
def toDateString():
|
||||
check_date(this)
|
||||
return this.local_strftime('%d %B %Y')
|
||||
|
||||
def toTimeString():
|
||||
check_date(this)
|
||||
return this.local_strftime('%H:%M:%S')
|
||||
|
||||
def toLocaleString():
|
||||
check_date(this)
|
||||
return this.local_strftime('%d %B %Y %H:%M:%S')
|
||||
|
||||
def toLocaleDateString():
|
||||
check_date(this)
|
||||
return this.local_strftime('%d %B %Y')
|
||||
|
||||
def toLocaleTimeString():
|
||||
check_date(this)
|
||||
return this.local_strftime('%H:%M:%S')
|
||||
|
||||
def valueOf():
|
||||
check_date(this)
|
||||
return this.value
|
||||
|
||||
def getTime():
|
||||
check_date(this)
|
||||
return this.value
|
||||
|
||||
def getFullYear():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return YearFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCFullYear():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return YearFromTime(this.value)
|
||||
|
||||
def getMonth():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return MonthFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getDate():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return DateFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCMonth():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return MonthFromTime(this.value)
|
||||
|
||||
def getUTCDate():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return DateFromTime(this.value)
|
||||
|
||||
def getDay():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return WeekDay(UTCToLocal(this.value))
|
||||
|
||||
def getUTCDay():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return WeekDay(this.value)
|
||||
|
||||
def getHours():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return HourFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCHours():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return HourFromTime(this.value)
|
||||
|
||||
def getMinutes():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return MinFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCMinutes():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return MinFromTime(this.value)
|
||||
|
||||
def getSeconds():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return SecFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCSeconds():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return SecFromTime(this.value)
|
||||
|
||||
def getMilliseconds():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return msFromTime(UTCToLocal(this.value))
|
||||
|
||||
def getUTCMilliseconds():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return msFromTime(this.value)
|
||||
|
||||
def getTimezoneOffset():
|
||||
check_date(this)
|
||||
if this.value is NaN:
|
||||
return NaN
|
||||
return (this.value - UTCToLocal(this.value)) // 60000
|
||||
|
||||
def setTime(time):
|
||||
check_date(this)
|
||||
this.value = TimeClip(time.to_number().to_int())
|
||||
return this.value
|
||||
|
||||
def setMilliseconds(ms):
|
||||
check_date(this)
|
||||
t = UTCToLocal(this.value)
|
||||
tim = MakeTime(
|
||||
HourFromTime(t), MinFromTime(t), SecFromTime(t), ms.to_int())
|
||||
u = TimeClip(LocalToUTC(MakeDate(Day(t), tim)))
|
||||
this.value = u
|
||||
return u
|
||||
|
||||
def setUTCMilliseconds(ms):
|
||||
check_date(this)
|
||||
t = this.value
|
||||
tim = MakeTime(
|
||||
HourFromTime(t), MinFromTime(t), SecFromTime(t), ms.to_int())
|
||||
u = TimeClip(MakeDate(Day(t), tim))
|
||||
this.value = u
|
||||
return u
|
||||
|
||||
# todo Complete all setters!
|
||||
|
||||
def toUTCString():
|
||||
check_date(this)
|
||||
return this.utc_strftime('%d %B %Y %H:%M:%S')
|
||||
|
||||
def toISOString():
|
||||
check_date(this)
|
||||
t = this.value
|
||||
year = YearFromTime(t)
|
||||
month, day, hour, minute, second, milli = pad(
|
||||
MonthFromTime(t) + 1), pad(DateFromTime(t)), pad(
|
||||
HourFromTime(t)), pad(MinFromTime(t)), pad(
|
||||
SecFromTime(t)), pad(msFromTime(t))
|
||||
return ISO_FORMAT % (unicode(year) if 0 <= year <= 9999 else pad(
|
||||
year, 6, True), month, day, hour, minute, second, milli)
|
||||
|
||||
def toJSON(key):
|
||||
o = this.to_object()
|
||||
tv = o.to_primitive('Number')
|
||||
if tv.Class == 'Number' and not tv.is_finite():
|
||||
return this.null
|
||||
toISO = o.get('toISOString')
|
||||
if not toISO.is_callable():
|
||||
raise this.MakeError('TypeError', 'toISOString is not callable')
|
||||
return toISO.call(o, ())
|
||||
|
||||
|
||||
def pad(num, n=2, sign=False):
|
||||
'''returns n digit string representation of the num'''
|
||||
s = unicode(abs(num))
|
||||
if len(s) < n:
|
||||
s = '0' * (n - len(s)) + s
|
||||
if not sign:
|
||||
return s
|
||||
if num >= 0:
|
||||
return '+' + s
|
||||
else:
|
||||
return '-' + s
|
||||
|
||||
|
||||
fill_prototype(DatePrototype, DateProto, default_attrs)
|
||||
|
||||
Date.define_own_property(
|
||||
'prototype', {
|
||||
'value': DatePrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
DatePrototype.define_own_property('constructor', {
|
||||
'value': Date,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
@@ -1,87 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Float32Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.float32))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.float32))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.float32))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Float32Array should be a multiple of 4')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Float32Array should be a multiple of 4')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 4)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.float32, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.float32))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Float32Array.create = Float32Array
|
||||
Float32Array.own['length']['value'] = Js(3)
|
||||
|
||||
Float32Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Float32ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Float32ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Float32Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Float32ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(4),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,87 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Float64Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.float64))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.float64))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.float64))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 8 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Float64Array should be a multiple of 8')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 8 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Float64Array should be a multiple of 8')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 8)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.float64, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.float64))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Float64Array.create = Float64Array
|
||||
Float64Array.own['length']['value'] = Js(3)
|
||||
|
||||
Float64Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Float64ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Float64ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Float64Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Float64ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(8),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,52 +0,0 @@
|
||||
from ..base import *
|
||||
try:
|
||||
from ..translators.translator import translate_js
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Function():
|
||||
# convert arguments to python list of strings
|
||||
a = [e.to_string().value for e in arguments.to_list()]
|
||||
body = ';'
|
||||
args = ()
|
||||
if len(a):
|
||||
body = '%s;' % a[-1]
|
||||
args = a[:-1]
|
||||
# translate this function to js inline function
|
||||
js_func = '(function (%s) {%s})' % (','.join(args), body)
|
||||
# now translate js inline to python function
|
||||
py_func = translate_js(js_func, '')
|
||||
# add set func scope to global scope
|
||||
# a but messy solution but works :)
|
||||
globals()['var'] = PyJs.GlobalObject
|
||||
# define py function and return it
|
||||
temp = executor(py_func, globals())
|
||||
temp.source = '{%s}' % body
|
||||
temp.func_name = 'anonymous'
|
||||
return temp
|
||||
|
||||
|
||||
def executor(f, glob):
|
||||
exec (f, globals())
|
||||
return globals()['PyJs_anonymous_0_']
|
||||
|
||||
|
||||
#new statement simply calls Function
|
||||
Function.create = Function
|
||||
|
||||
#set constructor property inside FunctionPrototype
|
||||
|
||||
fill_in_props(FunctionPrototype, {'constructor': Function}, default_attrs)
|
||||
|
||||
#attach prototype to Function constructor
|
||||
Function.define_own_property(
|
||||
'prototype', {
|
||||
'value': FunctionPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
#Fix Function length (its 0 and should be 1)
|
||||
Function.own['length']['value'] = Js(1)
|
||||
@@ -1,87 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Int16Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.int16))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.int16))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.int16))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 2 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Int16Array should be a multiple of 2')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 2 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Int16Array should be a multiple of 2')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 2)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.int16, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.int16))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Int16Array.create = Int16Array
|
||||
Int16Array.own['length']['value'] = Js(3)
|
||||
|
||||
Int16Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Int16ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Int16ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Int16Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Int16ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(2),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,87 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Int32Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.int32))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.int32))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.int32))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Int32Array should be a multiple of 4')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Int32Array should be a multiple of 4')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 4)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.int32, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.int32))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Int32Array.create = Int32Array
|
||||
Int32Array.own['length']['value'] = Js(3)
|
||||
|
||||
Int32Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Int32ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Int32ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Int32Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Int32ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(4),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,79 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Int8Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.int8))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.int8))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.int8))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int(len(a.obj) - offset)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.int8, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.int8))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Int8Array.create = Int8Array
|
||||
Int8Array.own['length']['value'] = Js(3)
|
||||
|
||||
Int8Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Int8ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Int8ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Int8Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Int8ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(1),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,157 +0,0 @@
|
||||
from ..base import *
|
||||
import math
|
||||
import random
|
||||
|
||||
Math = PyJsObject(prototype=ObjectPrototype)
|
||||
Math.Class = 'Math'
|
||||
|
||||
CONSTANTS = {
|
||||
'E': 2.7182818284590452354,
|
||||
'LN10': 2.302585092994046,
|
||||
'LN2': 0.6931471805599453,
|
||||
'LOG2E': 1.4426950408889634,
|
||||
'LOG10E': 0.4342944819032518,
|
||||
'PI': 3.1415926535897932,
|
||||
'SQRT1_2': 0.7071067811865476,
|
||||
'SQRT2': 1.4142135623730951
|
||||
}
|
||||
|
||||
for constant, value in CONSTANTS.items():
|
||||
Math.define_own_property(
|
||||
constant, {
|
||||
'value': Js(value),
|
||||
'writable': False,
|
||||
'enumerable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
|
||||
class MathFunctions:
|
||||
def abs(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return abs(a)
|
||||
|
||||
def acos(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
try:
|
||||
return math.acos(a)
|
||||
except:
|
||||
return NaN
|
||||
|
||||
def asin(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
try:
|
||||
return math.asin(a)
|
||||
except:
|
||||
return NaN
|
||||
|
||||
def atan(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.atan(a)
|
||||
|
||||
def atan2(y, x):
|
||||
a = x.to_number().value
|
||||
b = y.to_number().value
|
||||
if a != a or b != b: # it must be a nan
|
||||
return NaN
|
||||
return math.atan2(b, a)
|
||||
|
||||
def ceil(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.ceil(a)
|
||||
|
||||
def floor(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.floor(a)
|
||||
|
||||
def round(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return round(a)
|
||||
|
||||
def sin(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.sin(a)
|
||||
|
||||
def cos(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.cos(a)
|
||||
|
||||
def tan(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.tan(a)
|
||||
|
||||
def log(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
try:
|
||||
return math.log(a)
|
||||
except:
|
||||
return NaN
|
||||
|
||||
def exp(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
return math.exp(a)
|
||||
|
||||
def pow(x, y):
|
||||
a = x.to_number().value
|
||||
b = y.to_number().value
|
||||
if a != a or b != b: # it must be a nan
|
||||
return NaN
|
||||
try:
|
||||
return a**b
|
||||
except:
|
||||
return NaN
|
||||
|
||||
def sqrt(x):
|
||||
a = x.to_number().value
|
||||
if a != a: # it must be a nan
|
||||
return NaN
|
||||
try:
|
||||
return a**0.5
|
||||
except:
|
||||
return NaN
|
||||
|
||||
def min():
|
||||
if not len(arguments):
|
||||
return Infinity
|
||||
lis = tuple(e.to_number().value for e in arguments.to_list())
|
||||
if any(e != e for e in lis): # we dont want NaNs
|
||||
return NaN
|
||||
return min(*lis)
|
||||
|
||||
def max():
|
||||
if not len(arguments):
|
||||
return -Infinity
|
||||
lis = tuple(e.to_number().value for e in arguments.to_list())
|
||||
if any(e != e for e in lis): # we dont want NaNs
|
||||
return NaN
|
||||
return max(*lis)
|
||||
|
||||
def random():
|
||||
return random.random()
|
||||
|
||||
|
||||
fill_prototype(Math, MathFunctions, default_attrs)
|
||||
@@ -1,23 +0,0 @@
|
||||
from ..base import *
|
||||
|
||||
CONSTS = {
|
||||
'prototype': NumberPrototype,
|
||||
'MAX_VALUE': 1.7976931348623157e308,
|
||||
'MIN_VALUE': 5.0e-324,
|
||||
'NaN': NaN,
|
||||
'NEGATIVE_INFINITY': float('-inf'),
|
||||
'POSITIVE_INFINITY': float('inf')
|
||||
}
|
||||
|
||||
fill_in_props(Number, CONSTS, {
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
NumberPrototype.define_own_property('constructor', {
|
||||
'value': Number,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
@@ -1,198 +0,0 @@
|
||||
from ..base import *
|
||||
import six
|
||||
|
||||
#todo Double check everything is OK
|
||||
|
||||
|
||||
@Js
|
||||
def Object():
|
||||
val = arguments.get('0')
|
||||
if val.is_null() or val.is_undefined():
|
||||
return PyJsObject(prototype=ObjectPrototype)
|
||||
return val.to_object()
|
||||
|
||||
|
||||
@Js
|
||||
def object_constructor():
|
||||
if len(arguments):
|
||||
val = arguments.get('0')
|
||||
if val.TYPE == 'Object':
|
||||
#Implementation dependent, but my will simply return :)
|
||||
return val
|
||||
elif val.TYPE in ('Number', 'String', 'Boolean'):
|
||||
return val.to_object()
|
||||
return PyJsObject(prototype=ObjectPrototype)
|
||||
|
||||
|
||||
Object.create = object_constructor
|
||||
Object.own['length']['value'] = Js(1)
|
||||
|
||||
|
||||
class ObjectMethods:
|
||||
def getPrototypeOf(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.getPrototypeOf called on non-object')
|
||||
return null if obj.prototype is None else obj.prototype
|
||||
|
||||
def getOwnPropertyDescriptor(obj, prop):
|
||||
if not obj.is_object():
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Object.getOwnPropertyDescriptor called on non-object')
|
||||
return obj.own.get(
|
||||
prop.to_string().
|
||||
value) # will return undefined if we dont have this prop
|
||||
|
||||
def getOwnPropertyNames(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Object.getOwnPropertyDescriptor called on non-object')
|
||||
return obj.own.keys()
|
||||
|
||||
def create(obj):
|
||||
if not (obj.is_object() or obj.is_null()):
|
||||
raise MakeError('TypeError',
|
||||
'Object prototype may only be an Object or null')
|
||||
temp = PyJsObject(prototype=(None if obj.is_null() else obj))
|
||||
if len(arguments) > 1 and not arguments[1].is_undefined():
|
||||
if six.PY2:
|
||||
ObjectMethods.defineProperties.__func__(temp, arguments[1])
|
||||
else:
|
||||
ObjectMethods.defineProperties(temp, arguments[1])
|
||||
return temp
|
||||
|
||||
def defineProperty(obj, prop, attrs):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.defineProperty called on non-object')
|
||||
name = prop.to_string().value
|
||||
if not obj.define_own_property(name, ToPropertyDescriptor(attrs)):
|
||||
raise MakeError('TypeError', 'Cannot redefine property: %s' % name)
|
||||
return obj
|
||||
|
||||
def defineProperties(obj, properties):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.defineProperties called on non-object')
|
||||
props = properties.to_object()
|
||||
for name in props:
|
||||
desc = ToPropertyDescriptor(props.get(name.value))
|
||||
if not obj.define_own_property(name.value, desc):
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Failed to define own property: %s' % name.value)
|
||||
return obj
|
||||
|
||||
def seal(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError', 'Object.seal called on non-object')
|
||||
for desc in obj.own.values():
|
||||
desc['configurable'] = False
|
||||
obj.extensible = False
|
||||
return obj
|
||||
|
||||
def freeze(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError', 'Object.freeze called on non-object')
|
||||
for desc in obj.own.values():
|
||||
desc['configurable'] = False
|
||||
if is_data_descriptor(desc):
|
||||
desc['writable'] = False
|
||||
obj.extensible = False
|
||||
return obj
|
||||
|
||||
def preventExtensions(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.preventExtensions on non-object')
|
||||
obj.extensible = False
|
||||
return obj
|
||||
|
||||
def isSealed(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.isSealed called on non-object')
|
||||
if obj.extensible:
|
||||
return False
|
||||
for desc in obj.own.values():
|
||||
if desc['configurable']:
|
||||
return False
|
||||
return True
|
||||
|
||||
def isFrozen(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.isFrozen called on non-object')
|
||||
if obj.extensible:
|
||||
return False
|
||||
for desc in obj.own.values():
|
||||
if desc['configurable']:
|
||||
return False
|
||||
if is_data_descriptor(desc) and desc['writable']:
|
||||
return False
|
||||
return True
|
||||
|
||||
def isExtensible(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError',
|
||||
'Object.isExtensible called on non-object')
|
||||
return obj.extensible
|
||||
|
||||
def keys(obj):
|
||||
if not obj.is_object():
|
||||
raise MakeError('TypeError', 'Object.keys called on non-object')
|
||||
return [e for e, d in six.iteritems(obj.own) if d.get('enumerable')]
|
||||
|
||||
|
||||
# add methods attached to Object constructor
|
||||
fill_prototype(Object, ObjectMethods, default_attrs)
|
||||
# add constructor to prototype
|
||||
fill_in_props(ObjectPrototype, {'constructor': Object}, default_attrs)
|
||||
# add prototype property to the constructor.
|
||||
Object.define_own_property(
|
||||
'prototype', {
|
||||
'value': ObjectPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
# some utility functions:
|
||||
|
||||
|
||||
def ToPropertyDescriptor(obj): # page 38 (50 absolute)
|
||||
if obj.TYPE != 'Object':
|
||||
raise MakeError('TypeError',
|
||||
'Can\'t convert non-object to property descriptor')
|
||||
desc = {}
|
||||
if obj.has_property('enumerable'):
|
||||
desc['enumerable'] = obj.get('enumerable').to_boolean().value
|
||||
if obj.has_property('configurable'):
|
||||
desc['configurable'] = obj.get('configurable').to_boolean().value
|
||||
if obj.has_property('value'):
|
||||
desc['value'] = obj.get('value')
|
||||
if obj.has_property('writable'):
|
||||
desc['writable'] = obj.get('writable').to_boolean().value
|
||||
if obj.has_property('get'):
|
||||
cand = obj.get('get')
|
||||
if not (cand.is_undefined() or cand.is_callable()):
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Invalid getter (it has to be a function or undefined)')
|
||||
desc['get'] = cand
|
||||
if obj.has_property('set'):
|
||||
cand = obj.get('set')
|
||||
if not (cand.is_undefined() or cand.is_callable()):
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Invalid setter (it has to be a function or undefined)')
|
||||
desc['set'] = cand
|
||||
if ('get' in desc or 'set' in desc) and ('value' in desc
|
||||
or 'writable' in desc):
|
||||
raise MakeError(
|
||||
'TypeError',
|
||||
'Invalid property. A property cannot both have accessors and be writable or have a value.'
|
||||
)
|
||||
return desc
|
||||
@@ -1,16 +0,0 @@
|
||||
from ..base import *
|
||||
|
||||
RegExpPrototype.define_own_property('constructor', {
|
||||
'value': RegExp,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
RegExp.define_own_property(
|
||||
'prototype', {
|
||||
'value': RegExpPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,40 +0,0 @@
|
||||
from ..base import *
|
||||
# python 3 support
|
||||
import six
|
||||
if six.PY3:
|
||||
unichr = chr
|
||||
|
||||
|
||||
@Js
|
||||
def fromCharCode():
|
||||
args = arguments.to_list()
|
||||
res = u''
|
||||
for e in args:
|
||||
res += unichr(e.to_uint16())
|
||||
return this.Js(res)
|
||||
|
||||
|
||||
fromCharCode.own['length']['value'] = Js(1)
|
||||
|
||||
String.define_own_property(
|
||||
'fromCharCode', {
|
||||
'value': fromCharCode,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
String.define_own_property(
|
||||
'prototype', {
|
||||
'value': StringPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
StringPrototype.define_own_property('constructor', {
|
||||
'value': String,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
@@ -1,87 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Uint16Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.uint16))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.uint16))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.uint16))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 2 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Uint16Array should be a multiple of 2')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 2 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Uint16Array should be a multiple of 2')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 2)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.uint16, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.uint16))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Uint16Array.create = Uint16Array
|
||||
Uint16Array.own['length']['value'] = Js(3)
|
||||
|
||||
Uint16Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Uint16ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Uint16ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Uint16Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Uint16ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(2),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,95 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Uint32Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.uint32))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.uint32))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = len(array) - offset
|
||||
temp = Js(
|
||||
numpy.array(array[offset:offset + length], dtype=numpy.uint32))
|
||||
temp.put('length', Js(length))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(a.obj) % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Byte length of Uint32Array should be a multiple of 4')
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
if offset % 4 != 0:
|
||||
raise MakeError(
|
||||
'RangeError',
|
||||
'Start offset of Uint32Array should be a multiple of 4')
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int((len(a.obj) - offset) / 4)
|
||||
temp = Js(
|
||||
numpy.frombuffer(
|
||||
a.obj, dtype=numpy.uint32, count=length, offset=offset))
|
||||
temp.put('length', Js(length))
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.uint32))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Uint32Array.create = Uint32Array
|
||||
Uint32Array.own['length']['value'] = Js(3)
|
||||
|
||||
Uint32Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Uint32ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Uint32ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Uint32Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Uint32ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(4),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,79 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Uint8Array():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.uint8))
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.uint8))
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.uint8))
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int(len(a.obj) - offset)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.uint8, count=length, offset=offset)
|
||||
temp = Js(array)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.uint8))
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Uint8Array.create = Uint8Array
|
||||
Uint8Array.own['length']['value'] = Js(3)
|
||||
|
||||
Uint8Array.define_own_property(
|
||||
'prototype', {
|
||||
'value': Uint8ArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Uint8ArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Uint8Array,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Uint8ArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(1),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,79 +0,0 @@
|
||||
# this is based on jsarray.py
|
||||
|
||||
from ..base import *
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@Js
|
||||
def Uint8ClampedArray():
|
||||
TypedArray = (PyJsInt8Array, PyJsUint8Array, PyJsUint8ClampedArray,
|
||||
PyJsInt16Array, PyJsUint16Array, PyJsInt32Array,
|
||||
PyJsUint32Array, PyJsFloat32Array, PyJsFloat64Array)
|
||||
a = arguments[0]
|
||||
if isinstance(a, PyJsNumber): # length
|
||||
length = a.to_uint32()
|
||||
if length != a.value:
|
||||
raise MakeError('RangeError', 'Invalid array length')
|
||||
temp = Js(numpy.full(length, 0, dtype=numpy.uint8), Clamped=True)
|
||||
temp.put('length', a)
|
||||
return temp
|
||||
elif isinstance(a, PyJsString): # object (string)
|
||||
temp = Js(numpy.array(list(a.value), dtype=numpy.uint8), Clamped=True)
|
||||
temp.put('length', Js(len(list(a.value))))
|
||||
return temp
|
||||
elif isinstance(a, PyJsArray) or isinstance(a, TypedArray) or isinstance(
|
||||
a, PyJsArrayBuffer): # object (Array, TypedArray)
|
||||
array = a.to_list()
|
||||
array = [(int(item.value) if item.value != None else 0)
|
||||
for item in array]
|
||||
temp = Js(numpy.array(array, dtype=numpy.uint8), Clamped=True)
|
||||
temp.put('length', Js(len(array)))
|
||||
return temp
|
||||
elif isinstance(a, PyObjectWrapper): # object (ArrayBuffer, etc)
|
||||
if len(arguments) > 1:
|
||||
offset = int(arguments[1].value)
|
||||
else:
|
||||
offset = 0
|
||||
if len(arguments) > 2:
|
||||
length = int(arguments[2].value)
|
||||
else:
|
||||
length = int(len(a.obj) - offset)
|
||||
array = numpy.frombuffer(
|
||||
a.obj, dtype=numpy.uint8, count=length, offset=offset)
|
||||
temp = Js(array, Clamped=True)
|
||||
temp.put('length', Js(length))
|
||||
temp.buff = array
|
||||
return temp
|
||||
temp = Js(numpy.full(0, 0, dtype=numpy.uint8), Clamped=True)
|
||||
temp.put('length', Js(0))
|
||||
return temp
|
||||
|
||||
|
||||
Uint8ClampedArray.create = Uint8ClampedArray
|
||||
Uint8ClampedArray.own['length']['value'] = Js(3)
|
||||
|
||||
Uint8ClampedArray.define_own_property(
|
||||
'prototype', {
|
||||
'value': Uint8ClampedArrayPrototype,
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
|
||||
Uint8ClampedArrayPrototype.define_own_property(
|
||||
'constructor', {
|
||||
'value': Uint8ClampedArray,
|
||||
'enumerable': False,
|
||||
'writable': True,
|
||||
'configurable': True
|
||||
})
|
||||
|
||||
Uint8ClampedArrayPrototype.define_own_property('BYTES_PER_ELEMENT', {
|
||||
'value': Js(1),
|
||||
'enumerable': False,
|
||||
'writable': False,
|
||||
'configurable': False
|
||||
})
|
||||
@@ -1,207 +0,0 @@
|
||||
# NOTE: t must be INT!!!
|
||||
import time
|
||||
import datetime
|
||||
import warnings
|
||||
|
||||
try:
|
||||
from tzlocal import get_localzone
|
||||
LOCAL_ZONE = get_localzone()
|
||||
except: # except all problems...
|
||||
warnings.warn(
|
||||
'Please install or fix tzlocal library (pip install tzlocal) in order to make Date object work better. Otherwise I will assume DST is in effect all the time'
|
||||
)
|
||||
|
||||
class LOCAL_ZONE:
|
||||
@staticmethod
|
||||
def dst(*args):
|
||||
return 1
|
||||
|
||||
|
||||
from js2py.base import MakeError
|
||||
CUM = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365)
|
||||
msPerDay = 86400000
|
||||
msPerYear = int(86400000 * 365.242)
|
||||
msPerSecond = 1000
|
||||
msPerMinute = 60000
|
||||
msPerHour = 3600000
|
||||
HoursPerDay = 24
|
||||
MinutesPerHour = 60
|
||||
SecondsPerMinute = 60
|
||||
NaN = float('nan')
|
||||
LocalTZA = -time.timezone * msPerSecond
|
||||
|
||||
|
||||
def DaylightSavingTA(t):
|
||||
if t is NaN:
|
||||
return t
|
||||
try:
|
||||
return int(
|
||||
LOCAL_ZONE.dst(datetime.datetime.utcfromtimestamp(
|
||||
t // 1000)).seconds) * 1000
|
||||
except:
|
||||
warnings.warn(
|
||||
'Invalid datetime date, assumed DST time, may be inaccurate...',
|
||||
Warning)
|
||||
return 1
|
||||
#raise MakeError('TypeError', 'date not supported by python.datetime. I will solve it in future versions')
|
||||
|
||||
|
||||
def GetTimeZoneName(t):
|
||||
return time.tzname[DaylightSavingTA(t) > 0]
|
||||
|
||||
|
||||
def LocalToUTC(t):
|
||||
return t - LocalTZA - DaylightSavingTA(t - LocalTZA)
|
||||
|
||||
|
||||
def UTCToLocal(t):
|
||||
return t + LocalTZA + DaylightSavingTA(t)
|
||||
|
||||
|
||||
def Day(t):
|
||||
return t // 86400000
|
||||
|
||||
|
||||
def TimeWithinDay(t):
|
||||
return t % 86400000
|
||||
|
||||
|
||||
def DaysInYear(y):
|
||||
if y % 4:
|
||||
return 365
|
||||
elif y % 100:
|
||||
return 366
|
||||
elif y % 400:
|
||||
return 365
|
||||
else:
|
||||
return 366
|
||||
|
||||
|
||||
def DayFromYear(y):
|
||||
return 365 * (y - 1970) + (y - 1969) // 4 - (y - 1901) // 100 + (
|
||||
y - 1601) // 400
|
||||
|
||||
|
||||
def TimeFromYear(y):
|
||||
return 86400000 * DayFromYear(y)
|
||||
|
||||
|
||||
def YearFromTime(t):
|
||||
guess = 1970 - t // 31556908800 # msPerYear
|
||||
gt = TimeFromYear(guess)
|
||||
if gt <= t:
|
||||
while gt <= t:
|
||||
guess += 1
|
||||
gt = TimeFromYear(guess)
|
||||
return guess - 1
|
||||
else:
|
||||
while gt > t:
|
||||
guess -= 1
|
||||
gt = TimeFromYear(guess)
|
||||
return guess
|
||||
|
||||
|
||||
def DayWithinYear(t):
|
||||
return Day(t) - DayFromYear(YearFromTime(t))
|
||||
|
||||
|
||||
def InLeapYear(t):
|
||||
y = YearFromTime(t)
|
||||
if y % 4:
|
||||
return 0
|
||||
elif y % 100:
|
||||
return 1
|
||||
elif y % 400:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
def MonthFromTime(t):
|
||||
day = DayWithinYear(t)
|
||||
leap = InLeapYear(t)
|
||||
if day < 31:
|
||||
return 0
|
||||
day -= leap
|
||||
if day < 59:
|
||||
return 1
|
||||
elif day < 90:
|
||||
return 2
|
||||
elif day < 120:
|
||||
return 3
|
||||
elif day < 151:
|
||||
return 4
|
||||
elif day < 181:
|
||||
return 5
|
||||
elif day < 212:
|
||||
return 6
|
||||
elif day < 243:
|
||||
return 7
|
||||
elif day < 273:
|
||||
return 8
|
||||
elif day < 304:
|
||||
return 9
|
||||
elif day < 334:
|
||||
return 10
|
||||
else:
|
||||
return 11
|
||||
|
||||
|
||||
def DateFromTime(t):
|
||||
mon = MonthFromTime(t)
|
||||
day = DayWithinYear(t)
|
||||
return day - CUM[mon] - (1 if InLeapYear(t) and mon >= 2 else 0) + 1
|
||||
|
||||
|
||||
def WeekDay(t):
|
||||
# 0 == sunday
|
||||
return (Day(t) + 4) % 7
|
||||
|
||||
|
||||
def msFromTime(t):
|
||||
return t % 1000
|
||||
|
||||
|
||||
def SecFromTime(t):
|
||||
return (t // 1000) % 60
|
||||
|
||||
|
||||
def MinFromTime(t):
|
||||
return (t // 60000) % 60
|
||||
|
||||
|
||||
def HourFromTime(t):
|
||||
return (t // 3600000) % 24
|
||||
|
||||
|
||||
def MakeTime(hour, Min, sec, ms):
|
||||
# takes PyJs objects and returns t
|
||||
if not (hour.is_finite() and Min.is_finite() and sec.is_finite()
|
||||
and ms.is_finite()):
|
||||
return NaN
|
||||
h, m, s, milli = hour.to_int(), Min.to_int(), sec.to_int(), ms.to_int()
|
||||
return h * 3600000 + m * 60000 + s * 1000 + milli
|
||||
|
||||
|
||||
def MakeDay(year, month, date):
|
||||
# takes PyJs objects and returns t
|
||||
if not (year.is_finite() and month.is_finite() and date.is_finite()):
|
||||
return NaN
|
||||
y, m, dt = year.to_int(), month.to_int(), date.to_int()
|
||||
y += m // 12
|
||||
mn = m % 12
|
||||
d = DayFromYear(y) + CUM[mn] + dt - 1 + (1 if DaysInYear(y) == 366
|
||||
and mn >= 2 else 0)
|
||||
return d # ms per day
|
||||
|
||||
|
||||
def MakeDate(day, time):
|
||||
return 86400000 * day + time
|
||||
|
||||
|
||||
def TimeClip(t):
|
||||
if t != t or abs(t) == float('inf'):
|
||||
return NaN
|
||||
if abs(t) > 8.64 * 10**15:
|
||||
return NaN
|
||||
return int(t)
|
||||
Reference in New Issue
Block a user