lucab
9a87e41332
fix(parser): avoid crashing on invalid const modifier ( #4267 )
...
Followup on https://github.com/oxc-project/oxc/pull/3977 , fixing one of the crashes at https://github.com/oxc-project/oxc/pull/3977 .
2024-07-15 11:37:31 +00:00
Boshen
a71787572e
chore: remove unsafe_code = "warn" rust lint
...
Feels too verbose as we already have unsafe comment turned on
2024-07-15 10:39:08 +08:00
Dunqing
ace4f1ff77
refactor(semantic): update the order of visit_function and Visit fields in the builder to be consistent ( #4248 )
...
Same as #4195
2024-07-14 11:39:15 +00:00
Boshen
83bd40db4e
chore: turn off doctest for all [[bin]]
2024-07-14 16:55:19 +08:00
Boshen
e167ef79c6
fix(codegen): print parenthesis properly ( #4245 )
...
`TSParenthesizedType` handles parenthesis in ts types.
It should be considered a bug if parenthesis is not printed correctly after this PR.
2024-07-14 04:13:10 +00:00
Dunqing
dc2b3c44fb
refactor(semantic): add strict mode in scope flags for class definitions ( #4156 )
...
related: https://github.com/oxc-project/oxc/issues/4142#issuecomment-2219125356
Although we called `enter_node(Class)`, that doesn't mean we're in the `class` scope. It causes our must to visit decorators before `enter_node`.
Let's look at this case. It causes a syntax error if we don't visit decorators before `enter_node`
```js
// This file was procedurally generated from the following sources:
// - src/decorator/decorator-call-expr-identifier-reference-yield.case
// - src/decorator/syntax/valid/cls-expr-decorators-valid-syntax.template
/*---
description: Decorator @ DecoratorCallExpression (Valid syntax for decorator on class expression)
esid: prod-ClassExpression
features: [class, decorators]
flags: [generated, noStrict]
info: |
ClassExpression[Yield, Await] :
DecoratorList[?Yield, ?Await]opt class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await]
DecoratorList[Yield, Await] :
DecoratorList[?Yield, ?Await]opt Decorator[?Yield, ?Await]
Decorator[Yield, Await] :
@ DecoratorMemberExpression[?Yield, ?Await]
@ DecoratorParenthesizedExpression[?Yield, ?Await]
@ DecoratorCallExpression[?Yield, ?Await]
...
DecoratorCallExpression[Yield, Await] :
DecoratorMemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
DecoratorMemberExpression[Yield, Await] :
IdentifierReference[?Yield, ?Await]
DecoratorMemberExpression[?Yield, ?Await] . IdentifierName
DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier
IdentifierReference[Yield, Await] :
[~Yield] yield
...
---*/
function decorator() {
return () => {};
}
var yield = decorator;
var C = @yield() class {};
```
Errors:
```shell
× The keyword 'yield' is reserved
╭─[language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js:45:2]
44 │
45 │ @yield() class C {}
· ─────
╰────
```
The changed code makes more sense. Only if we call `enter_scope` for class, the flags will contain `StrictMode`. Also, we can get the exact `flags` of the `scope` in the `class` at the transformer
For example:
```
class A {
B() {
// Before: flags is `Function`
// After: flags is `Function | StrictMode`
}
}
```
The regression tests will be fixed in follow-up PRs
2024-07-14 03:35:12 +00:00
Dunqing
20cdb1fe0a
feat(semantic): align class scope with typescript ( #4195 )
...
```ts
class Klass <T> extends Root <R> {}
// ^^^^^ ^^^ ^^^^ ^^^ ^^
// id type_paramter super_class super_type_parameters body
```
I reorder fields according to the order above
The class scope is not defined in the spec. But we need to create a scope for `class` to store `TypeParamters`
2024-07-14 03:19:30 +00:00
Boshen
c65198fa15
fix(codegen): choose the right quote for jsx attribute string ( #4236 )
2024-07-12 17:30:24 +00:00
Boshen
be82c286d6
fix(codegen): print JSXAttributeValue::StringLiteral directly ( #4231 )
...
jsx attribute string is interpreted as is without escaping.
The transformer is responsible for converting it to plain js string.
2024-07-12 16:17:23 +00:00
Dunqing
92ee77487f
feat(semantic): add ScopeFlags::CatchClause for use in CatchClause ( #4205 )
2024-07-12 03:47:07 +00:00
rzvxa
aab7aaaa06
refactor(ast/visit): fire node events as the outermost one. ( #4203 )
...
I'm going to be AFK today(till about 9 PM UTC). Meanwhile, I Didn't want to be a blocker so here we go.
It would fix the #4200 merge if you guys find it in the correct order otherwise feel free to close it.
2024-07-12 03:27:59 +00:00
Boshen
83c2c62f7b
feat(codegen): add option for choosing quotes; remove slow choose_quot method ( #4219 )
2024-07-12 03:08:22 +00:00
Boshen
91dc0f7866
chore(benchmark): add codegen benchmark ( #4207 )
2024-07-11 23:58:37 +08:00
Boshen
33e96e23e4
feat(tasks/minsize): include esbuild minified size ( #4202 )
2024-07-11 13:02:32 +00:00
Boshen
bb646f2bf9
feat(tasks/minsize): show target size for easier comparison ( #4201 )
2024-07-11 12:38:45 +00:00
IWANABETHATGUY
1c117eb20d
fix: avoid print extra semicolon after accessor property ( #4199 )
...
## Before
```js
export default class Foo { @x @y accessor #aDef = 1 }
```
**output**
```bash
Original:
export default class Foo { @x @y accessor #aDef = 1 }
Printed:
export default class Foo {
accessor #aDef=1;;
}
```
2024-07-11 20:16:02 +08:00
Boshen
e3e663bae4
feat(mangler): initialize crate and integrate into minifier ( #4197 )
2024-07-11 10:35:13 +00:00
Dunqing
bbe5dede07
refactor(semantic): set current_scope_id to scope_id in enter_scope ( #4193 )
...
close : #4170
2024-07-11 08:45:35 +00:00
Dunqing
7f1adddaf0
refactor(semantic): correct scope in CatchClause ( #4192 )
...
close : #4186
CatchClause has two scopes. The first one is `CatchClause`, which will add a `CatchParameter` to it. The second one is `Block`, which will add binding that declares in the current block scope.
The spec has a syntax error about `CatchParameter`
- It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the LexicallyDeclaredNames of Block.
2024-07-11 08:45:30 +00:00
Boshen
8c54a2f1ed
fix(tasks/ast_codegen): run cargo fmt synchronously ( #4181 )
...
relates #4152
This is my wild guess, because it works in my other script 143685deb1/xtask/src/main.rs (L21)
2024-07-11 02:59:30 +00:00
Boshen
ca0b4fa08a
refactor(tasks): clean up test files and remove libs.txt ( #4172 )
2024-07-10 17:38:06 +00:00
DonIsaac
4a656c3a18
fix(lexer): incorrect lexing of large hex/octal/binary literals ( #4072 )
...
Closes #3347 . Implementation follows the approach described by @overlookmotel [here](https://github.com/oxc-project/oxc/issues/3347#issuecomment-2119004288 ).
2024-07-10 16:39:10 +00:00
rzvxa
67fe75ec6c
feat(ast, ast_codegen): pass the scope_id to the enter_scope event. ( #4168 )
2024-07-10 15:19:23 +00:00
Boshen
28eeee0f71
fix(parser): fix asi error diagnostic pointing at invalid text causing crash ( #4163 )
2024-07-10 14:45:10 +00:00
rzvxa
3ba7cfed1f
feat(ast_codegen): add #[visit(enter_before)] hint. ( #4147 )
...
Closes #4142
I can split it into 2 PRs but it seems pointless. Let me know if you guys disagree with me.
2024-07-10 14:02:29 +00:00
Luca Bruno
5731e3957f
refactor(ast)!: store span details inside comment struct ( #4132 )
...
This tweaks `Comment` definition in order to internally store the start
and end position of its span.
Closes: https://github.com/oxc-project/oxc/issues/4069
2024-07-09 23:23:43 +08:00
rzvxa
0b433108be
feat(ast_codegen): add cli arguments to use with oxc_ast_codegen executable. ( #4117 )
...
```
Usage: oxc_ast_codegen [--dry-run] [--no-fmt] [--schema=ARG]
Available options:
--dry-run Runs all generators but won't write anything down.
--no-fmt Don't run cargo fmt at the end
--schema=ARG Path of output `schema.json`.
-h, --help Prints help information
```
2024-07-09 03:42:11 +00:00
rzvxa
6db630fab3
refactor(ast_codegen): cleanup usages of the generated outputs. ( #4116 )
2024-07-09 03:42:05 +00:00
DonIsaac
2f53bdf72d
feat(semantic): check for abstract ClassElements in non-abstract classes ( #4127 )
...
feat(semantic): check for abstract ClassElements in non-abstract classes
chore: update coverage snapshots
2024-07-09 03:35:32 +00:00
DonIsaac
3a0f2aa7ef
feat(parser): check for illegal modifiers in modules and namespaces ( #4126 )
2024-07-09 02:54:06 +00:00
rzvxa
91c792a2ce
feat(ast_codegen): add ast builder generator. ( #4098 )
2024-07-09 00:47:23 +00:00
Don Isaac
c4ee9f8ec6
feat(semantic): check for abstract initializations and implementations ( #4125 )
2024-07-08 17:30:16 -04:00
Don Isaac
0f026089d1
fix(semantic): bind TSImportEqualsDeclarations ( #4100 )
...
Closes #4091
2024-07-08 14:03:47 +08:00
Don Isaac
4413e2d298
fix(transformer): missing initializer for readonly consructor properties ( #4103 )
2024-07-08 12:45:50 +08:00
DonIsaac
e386b62331
feat(semantic): check for invalid type import assignments ( #4097 )
...
Adds checks to `TSImportEqualsDeclaration` for invalid use of `import type` modifier.
```ts
import { Foo } from './foo'
namespace Bar {
export class Baz {}
}
import type A = Foo.Baz; // not allowed
import type B = Bar.Baz; // not allowed
import type C = require('./c'); // allowed
```
2024-07-08 03:14:22 +00:00
renovate[bot]
57d821b93c
chore(deps): update npm packages ( #4092 )
...
[](https://renovatebot.com )
This PR contains the following updates:
| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pnpm](https://pnpm.io ) ([source](https://togithub.com/pnpm/pnpm )) |
[`9.4.0` -> `9.5.0`](https://renovatebot.com/diffs/npm/pnpm/9.4.0/9.5.0 )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
| [wasm-pack](https://togithub.com/rustwasm/wasm-pack ) | [`^0.12.1` ->
`^0.13.0`](https://renovatebot.com/diffs/npm/wasm-pack/0.12.1/0.13.0 ) |
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
[](https://docs.renovatebot.com/merge-confidence/ )
|
---
### Release Notes
<details>
<summary>pnpm/pnpm (pnpm)</summary>
###
[`v9.5.0`](https://togithub.com/pnpm/pnpm/compare/v9.5.0-beta.3...v9.5.0 )
[Compare Source](https://togithub.com/pnpm/pnpm/compare/v9.4.0...v9.5.0 )
</details>
<details>
<summary>rustwasm/wasm-pack (wasm-pack)</summary>
###
[`v0.13.0`](https://togithub.com/rustwasm/wasm-pack/blob/HEAD/CHANGELOG.md#-0130 )
[Compare
Source](https://togithub.com/rustwasm/wasm-pack/compare/v0.12.1...v0.13.0 )
- ### ✨ Features
- **Add option to skip optimization with wasm-opt - [sisou],
[pull/1321]**
This feature introduces the `--no-opt` option to wasm-pack, providing a
significant improvement in build efficiency for projects requiring
multiple wasm-pack executions.
[pull/1321]: https://togithub.com/rustwasm/wasm-pack/pull/1321
[sisou]: https://togithub.com/sisou
- **Add support geckodriver for linux-aarch64 - [EstebanBorai],
[pull/1371]**
Introduces support to download Geckodriver in Linux aarch64.
[pull/1371]: https://togithub.com/rustwasm/wasm-pack/pull/1371
[EstebanBorai]: https://togithub.com/EstebanBorai
- **Add wasm-opt linux aarch64 condition - [dkristia], [issue/1392],
[pull/1393]**
A linux aarch64 build for wasm-opt exists in the newest binaryen
versions.
[issue/1392]: https://togithub.com/rustwasm/wasm-pack/issues/1392
[pull/1393]: https://togithub.com/rustwasm/wasm-pack/pull/1393
[dkristia]: https://togithub.com/dkristia
- ### 🤕 Fixes
- **Fix passing relative paths to cargo - [dfaust], [issue/704],
[issue/1156], [issue/1252], [pull/1331]**
When building a crate located in a sub-directory, relative paths, passed
as extra options to cargo (like `--target-dir`), are now handled
correctly.
[issue/704]: https://togithub.com/rustwasm/wasm-pack/issues/704
[issue/1156]: https://togithub.com/rustwasm/wasm-pack/issues/1156
[issue/1252]: https://togithub.com/rustwasm/wasm-pack/issues/1252
[pull/1331]: https://togithub.com/rustwasm/wasm-pack/pull/1331
[dfaust]: https://togithub.com/dfaust
- **Rewrite wasm_target to use target-libdir - [daidoji], [issue/1342],
[pull/1343]**
Rewritten wasm_target to use target libdir from the rustc tool rather
than looking through sysroot. This is to accomodate non-rustup
installations.
[issue/1342]: https://togithub.com/rustwasm/wasm-pack/issues/1342
[pull/1343]: https://togithub.com/rustwasm/wasm-pack/pull/1343
[daidoji]: https://togithub.com/daidoji
- **Declare ES module in package.json - [gthb], [issue/1039],
[pull/1061]**
In bundler mode, generate package.json with "type": "module" and use the
"main" attribute instead of the "module" attribute.
This change makes the built ES module palatable to Node.js (when run
with --experimental-vm-modules --experimental-wasm-modules),
while it remains also palatable to webpack as illustrated in
[webpack/webpack#14313 ](https://togithub.com/webpack/webpack/issues/14313 )
(where the pkg subfolder is generated with wasm-pack built with this
change).
This resolves the headache of using a wasm-pack-built package in a
library that one needs to both run directly in Node and include in a
webpack build.
[issue/1039]: https://togithub.com/rustwasm/wasm-pack/issues/1039
[pull/1061]: https://togithub.com/rustwasm/wasm-pack/pull/1061
[gthb]: https://togithub.com/gthb
- **Use new chromdriver endpoint and fix CI - [Myriad-Dreamin],
[kade-robertson], [issue/1315], [issue/1390], [pull/1325], [pull/1391]**
[issue/1315]: https://togithub.com/rustwasm/wasm-pack/issues/1315
[issue/1390]: https://togithub.com/rustwasm/wasm-pack/issues/1390
[pull/1325]: https://togithub.com/rustwasm/wasm-pack/pull/1325
[pull/1391]: https://togithub.com/rustwasm/wasm-pack/pull/1391
[Myriad-Dreamin]: https://togithub.com/Myriad-Dreamin
[kade-robertson]: https://togithub.com/kade-robertson
- **Add mingw support to npm package - [nathaniel-daniel], [issue/1354],
[issue/1359], [pull/1363]**
Fixes the NPM package's platform detection for mingw.
[issue/1354]: https://togithub.com/rustwasm/wasm-pack/issues/1354
[issue/1359]: https://togithub.com/rustwasm/wasm-pack/issues/1359
[pull/1363]: https://togithub.com/rustwasm/wasm-pack/pull/1363
[nathaniel-daniel]: https://togithub.com/nathaniel-daniel
- **pkg-dir option for pack and publish commands - [danielronnkvist],
[issue/1369], [pull/1370]**
To be able to use these commands when the output directory option to the
build command isn't the default pkg.
[issue/1369]: https://togithub.com/rustwasm/wasm-pack/issues/1369
[pull/1370]: https://togithub.com/rustwasm/wasm-pack/pull/1370
[danielronnkvist]: https://togithub.com/danielronnkvist
- **Optimize out-dir display - [ahaoboy], [issue/1395], [pull/1396]**
Optimize out-dir display.
from:
`[INFO]: 📦 Your wasm pkg is ready to publish at
/root/code/fib-wasm/fib-rs/../fib-wasm/wasm.`
to:
`[INFO]: 📦 Your wasm pkg is ready to publish at
/root/code/fib-wasm/fib-wasm/wasm.`
[issue/1395]: https://togithub.com/rustwasm/wasm-pack/issues/1395
[pull/1396]: https://togithub.com/rustwasm/wasm-pack/pull/1396
[ahaoboy]: https://togithub.com/ahaoboy
- ### 🛠️ Maintenance
- **Fix error and warnings in install script - [lucashorward],
[issue/1159], [issue/1217], [issue/1283], [pull/1320]**
[issue/1159]: https://togithub.com/rustwasm/wasm-pack/issues/1159
[issue/1217]: https://togithub.com/rustwasm/wasm-pack/issues/1217
[issue/1283]: https://togithub.com/rustwasm/wasm-pack/issues/1283
[pull/1320]: https://togithub.com/rustwasm/wasm-pack/pull/1320
[lucashorward]: https://togithub.com/lucashorward
- **Bump follow-redirects from 1.14.9 to 1.15.6 in /npm - [dependabot],
[pull/1375]**
[pull/1375]: https://togithub.com/rustwasm/wasm-pack/pull/1375
- **Bump rustls-webpki from 0.100.1 to 0.100.2 - [dependabot],
[pull/1323]**
[pull/1341]: https://togithub.com/rustwasm/wasm-pack/pull/1341
- **Bump rustix from 0.37.20 to 0.37.25 - [dependabot], [pull/1341]**
[pull/1323]: https://togithub.com/rustwasm/wasm-pack/pull/1323
[dependabot]: https://togithub.com/apps/dependabot
- **Bump rustls from 0.21.9 to 0.21.11 - [dependabot], [pull/1385]**
[pull/1385]: https://togithub.com/rustwasm/wasm-pack/pull/1385
[dependabot]: https://togithub.com/apps/dependabot
- **Bump tar from 6.1.11 to 6.2.1 in /npm - [dependabot], [pull/1379]**
[pull/1379]: https://togithub.com/rustwasm/wasm-pack/pull/1379
[dependabot]: https://togithub.com/apps/dependabot
- ### 📖 Documentation
- **Fix typo in README - [Lionelf329], \[pull/1368]**
[pull/1268]: https://togithub.com/rustwasm/wasm-pack/pull/1368
[Lionelf329]: https://togithub.com/Lionelf329
- **Add a description of build --target deno - [puxiao], [pull/1344]**
[pull/1344]: https://togithub.com/rustwasm/wasm-pack/pull/1344
[puxiao]: https://togithub.com/puxiao
- **Document deno in build target - [sigmaSd], [pull/1348]**
[pull/1348]: https://togithub.com/rustwasm/wasm-pack/pull/1348
[sigmaSd]: https://togithub.com/sigmaSd
- **Fix local navigation backing one step too far in docs - [SamuSoft],
[pull/1387]**
[pull/1387]: https://togithub.com/rustwasm/wasm-pack/pull/1387
[SamuSoft]: https://togithub.com/SamuSoft
- **Add --target web to quick start build command - [josephrocca],
[pull/1367]**
[pull/1367]: https://togithub.com/rustwasm/wasm-pack/pull/1367
[josephrocca]: https://togithub.com/josephrocca
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "before 10am on monday" in timezone
Asia/Shanghai, Automerge - At any time (no schedule defined).
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions ) if
that's undesired.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/ ). View
repository job log
[here](https://developer.mend.io/github/oxc-project/oxc ).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MjEuOSIsInVwZGF0ZWRJblZlciI6IjM3LjQyMS45IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-07 18:33:47 +00:00
Boshen
6e5447e5d5
chore(coverage): add test for huge binary expression and nested if statements ( #4084 )
...
relates https://github.com/oxc-project/backlog/issues/58
2024-07-08 00:15:26 +08:00
Boshen
0ba375899c
chore(tasks/benchmark): add isolated_declarations bench
2024-07-07 19:22:49 +08:00
Dunqing
54b3b6c0da
chore(benchmark): add isolated declarations ( #4078 )
2024-07-07 17:14:48 +08:00
mysteryven
4414774d7d
chore(tasks/rulegen): generate options for fix cases ( #4076 )
...
Our fixer support rule option, and we need to generate `options` for them.
328445b4ca/crates/oxc_linter/src/tester.rs (L238)
cc @eryue0220
2024-07-07 03:01:55 +00:00
rzvxa
aa585d31e1
fix(ast_codegen, ast): visit ExpressionArrayElement as Expression. ( #4061 )
...
hotfix for #4060
I just added an edge case, We can come back to it later on and make it a
standard in our codegen.
The diff is big because it causes the code to reorder, The edge case
generated code doesn't follow the order in which they are defined in the
source of truth(eg `js.rs`)
2024-07-06 00:29:36 +08:00
Boshen
aaac2d8775
fix(codegen): preserve parentheses from AST instead calculating from operator precedence ( #4055 )
...
…operator precedence
Calculating from operator precedence is currently unsafe and will result
incorrect semantics.
2024-07-05 14:01:17 +08:00
Boshen
09cc760475
chore(tasks/benchmark): turn on jsdoc parsing in semantic benchmark
2024-07-04 00:00:52 +08:00
Boshen
243c9f35b0
refactor(parser): use function instead of trait to parse list with rest element ( #4028 )
...
closes #3887
2024-07-02 13:43:14 +00:00
rzvxa
1854a52bd7
feat(ast_codegen): introduce the #[span] hint. ( #4012 )
...
closes #3904
2024-07-02 10:18:58 +00:00
rzvxa
71e9286fa6
improvement(ast_codegen): use visit_as attribute to create aliased AstKinds. ( #4011 )
2024-07-02 10:18:56 +00:00
rzvxa
352c0b4103
pref(ast): inline visit walks with small bodies. ( #4009 )
...
~~Attempt to improve the performance of visitors, It is mostly for experiments. I'm not sure how much performance is there to gain back.~~
- [x] inline plural visits (eg: visit_statements)
- [x] inline enums when there are 5 or fewer match cases
- [x] inline structs when there are 5 or less fields
- [x] inline `Visit::alloc`
2024-07-02 10:18:55 +00:00
rzvxa
b51f75baf8
refactor(ast_codegen): no longer outputs discard variable for empty visitors. ( #4008 )
2024-07-02 10:18:53 +00:00
rzvxa
272df6ee90
feat(ast_codegen): support for generating VisitMut. ( #4006 )
2024-07-02 10:18:49 +00:00
rzvxa
7538af12d8
feat(ast_codegen): add visit generator ( #3954 )
...
~~The generated code is only here for the sake of my own comparison (instead of manually keeping a backup of the old generated file). I would clean this up as soon as it is ready, submit some parts of it as the down stack, and stack the actual generated code on top of this. So please don't let the huge diff distract you, It won't have many conflicts since almost all of these are the generated visit code, which is completely contained to its own module(other than some minor renaming refactors).~~
The order of function definitions is a bit different, I've used a depth-first search, We can switch to a breadth-first one to align functions more closely to the original.
2024-07-02 10:18:45 +00:00