Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38936
Unit tests that validate we continue to return correct measurement results through the lifetime of the list when cells are unmounted, or layout of the list shifts.
Changelog: [Internal]
Reviewed By: lenaic
Differential Revision: D47978632
fbshipit-source-id: b700fafb699e8820de6825f0ead1ef02c6d8f168
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38858
Pull Request resolved: https://github.com/facebook/react-native/pull/38328
This diff adds the two extra markers `initializeRuntimeStart` and `initializeRuntimeEnd` to the startup performance API. The runtime start time matches the existing android marker `GET_REACT_INSTANCE_MANAGER_START`, which is the first marker we have on the RN android app.
Changelog:
[Android][Added] - Add `performance.reactNativeStartupTiming.initializeRuntimeStart` and `performance.reactNativeStartupTiming.initializeRuntimeEnd` API
Reviewed By: rshest
Differential Revision: D47941110
fbshipit-source-id: d7e65f822f1c60a46dccacc8fd5bba84174f9f31
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39028
The regular expressions that we use to ignore other platform suffixes are wrong or unnecessarily complicated.
This diff cleans them up to be idiomatic regular expressions without any extra constructs.
Changelog:
[Internal]
Reviewed By: samwgoldman
Differential Revision: D48377329
fbshipit-source-id: e6d6c36b3dd6f524cc28a3cfb2938abb06dd8ab6
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39012
Upgrades many of our projects to `v8-compile-cache@^2.4.0`, which includes [zertosh/v8-compile-cache#45](https://github.com/zertosh/v8-compile-cache/pull/45). This fixes a very opaque segmentation fault when `v8-compile-cache` is used on Apple Silicon with mixed architecture modes.
This also upgrades our projects to `eslint@^2.3.1`, which no longer has the dependency on an outdated version of `v8-compile-cache`.
Changelog:
[Internal]
Reviewed By: zertosh, NickGerleman
Differential Revision: D48336030
fbshipit-source-id: afa73d1f00bff826a8b76fa09949b9d35a97905b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39008
Changelog: [Internal] - Adjust RawPropsPropNameLength's type to account for increased number of props
While investigating why we needed to back out D48288752 I discovered that the root cause was that the `items_` vector in `RawProsKeyMap` was now a size greater than 255 which becomes an issue because `items_`'s indices are statically cast to `RawPropsPropNameLength` (previously alias to `uint8_t`).
This diff updates `RawPropsPropNameLength` to be an alias to `uint16_t` so the current issue is resolved as well as adding an assert to ensure (however unlikely) that this happens again.
Reviewed By: rozele
Differential Revision: D48331909
fbshipit-source-id: f6bc3e4825f2f293d79d8cd90c40ced7cba0e3c5
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38911
Flipper is going to be deprecated in 0.73. So we can decide to remove the CircleCI tests that run Flipper:
- test_ios_template-NewArch-Debug-WithFlipper-Hermes-StaticLibraries
- test_ios_template-NewArch-Debug-WithFlipper-JSC-StaticLibraries
- test_ios_template-OldArch-Debug-WithFlipper-JSC-StaticLibraries
Changelog:
[Internal] [Changed] - Remove Flipper jobs from Circle CI
Reviewed By: cipolleschi
Differential Revision: D48209184
fbshipit-source-id: f43613d17093c4cc883409d4f083c577da924b78
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38992
This Diff publishes the Hermes dSYMs to Maven while doing a release.
These were missing and so the Stack traces can't be fully symbolicated when a crash occurs.
## Changelog:
[Internal] - Publish dSYM to Maven
Reviewed By: cortinico
Differential Revision: D48309198
fbshipit-source-id: a5514e544587daadd0a0d7614f25a30fccd16a5b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38983
Creates the dSYMs and store them as artifact in CircleCI
## Changelog:
[Internal] - Create the dSYM archive and upload it to CircleCI
Reviewed By: cortinico
Differential Revision: D48301851
fbshipit-source-id: 49c447b41573dcc567b3e62ad0b2a519562942c2
Summary:
This local change adds a script to poll Maven automatically after the release has happened.
This should allow the Release Crew not to repeatedly and manually refresh Maven urls in order to see whether the artifacts are there or not.
As soon as this job is green, artifacts are out!
Cost wise, we are using a small machine, which costs 5 credits per minute.
## Changelog:
[Internal] -Add script and CI job to poll for maven after a release.
Pull Request resolved: https://github.com/facebook/react-native/pull/38985
Test Plan:
Tested locally, running the JS script.
[Verified that the CI job can execute it.](https://app.circleci.com/pipelines/github/facebook/react-native/29634/workflows/5966d5f9-12ca-40b1-9185-758fe98d3aee/jobs/944107)
We can only test this for real while doing a proper release.
Reviewed By: cortinico
Differential Revision: D48309874
Pulled By: cipolleschi
fbshipit-source-id: 5c38b588c29c1311b1fa4e4ca44785583db0b701
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38987
As now we do have the buildTools version 34 in the docker container,
I'm bumping compileSdkVersion for all the targets to 34.
I'm also cleaning up the `test_windows` setup as it had old references
of NDK 20, build tools 33 and was installing the Android SDK but not
actually using it.
Changelog:
[Android] [Changed] - Bump Android compile-sdk to 34
Reviewed By: cipolleschi
Differential Revision: D48311828
fbshipit-source-id: c5b1d20a6183b577fba520af95b33e7656477101
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38958
changelog: [internal]
This is an unnecessary abstraction, let's remove it.
It originally served as a retry mechanism for C++ state update but it no longer serves that purpose. It obscures visibility into StateWrapper state.
jest_e2e[run_all_tests]
Reviewed By: mdvacca, luluwu2032
Differential Revision: D47993140
fbshipit-source-id: 81e81153d2de90f69d1495b14db66ee66670ba0f
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38988
- Upgrade to RN CLI `12.0.0-alpha.9`, including Metro bump to `0.78.0`.
- Update test scripts, since this CLI release made a breaking change to the `/status` response.
Changelog: [Internal]
Reviewed By: cortinico
Differential Revision: D48311214
fbshipit-source-id: bb0be3c32edb629355b9fbbd754b28f9878f47ef
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39004
Adds `flow` to this file. Even thought it is a stub, it still deserves to be checkable by Flow.
Changelog:
[Internal]
Reviewed By: SamChou19815
Differential Revision: D48325186
fbshipit-source-id: a3417bfa12258b85c1eb51744348a1c8aba63a8c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38990
This PR adds auto-generation of Typescript definitions from Flow source code for packages using the shared monorepo build setup (https://github.com/facebook/react-native/pull/38718).
Today, these are the following Node.js packages:
- `packages/community-cli-plugin`
- `packages/dev-middleware` (⬅️ `emitTypeScriptDefs` enabled)
This also improves emitted Flow definitions (`.js.flow`), by using [`flow-api-translator`](https://www.npmjs.com/package/flow-api-translator) to strip implementations.
**All changes**
- Include `flow-api-translator` and configure this to emit type definitions as part of `yarn build`.
- Add translation from Flow source to TypeScript definitions (`.d.ts`) adjacent to each built file.
- Improve emitted Flow definitions (`.js.flow`), by using `flow-api-translator` to strip implementations (previously, source files were copied). The Flow and TS defs now mirror each other.
- Add `emitFlowDefs` and `emitTypeScriptDefs` options to build config to configure the above.
- Integrate TypeScript compiler to perform program validation on emitted `.d.ts` files.
- This is based on this guide: https://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md#a-minimal-compiler.
- Throw an exception on the `rewritePackageExports` step if a package does not define an `"exports"` field.
- Add minimal `flow-typed` definitions for `typescript` 😄.
**Notes on [`flow-api-translator`](https://www.npmjs.com/package/flow-api-translator)**
This project is experimental but is in a more mature state than when we evaluated it earlier in 2023.
- It's now possible to run this tool on our new Node.js packages, since they are exclusively authored using `import`/`export` syntax (a requirement of the tool).
- As a safety net, we run the TypeScript compiler against the generated program, which will fail the build.
Changelog: [Internal]
Reviewed By: robhogan
Differential Revision: D48312463
fbshipit-source-id: 817edb35f911f52fa987946f2d8fc1a319078c9d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38706
Fabric has a mechanism to resolve conflicts when there are race conditions committing new versions in different threads. This mechanism forces commits to be done in order, retrying commits when they didn't have time to finish before another concurrent commit.
{F1061612667}
This mechanism has an important drawback. If we have a continuous stream of short commits (e.g.: animations via Reanimated) and we want to do a large commit (e.g.: coming from React), the large commit could exhaust all attempts to finish and ultimately fail. Every time we tried to commit the large one, another small one would have had a chance to finish, forcing another retry.
{F1061614717}
In most of the cases where this happens, we didn't even need to fail the commits in the first place!
**The only reason why we retry commits is so we make sure we are propagating the last state** (when state propagation is enabled in that commit). We don't reconcile the contents of the commits themselves (the tree we retry is exactly the same, if we exclude state).
We can reduce the number of reconciliation failures (and completely remove them in the case of animations) if instead of checking if the base revision for a commit changed, we checked if the version of the state we propagated changed.
We would have 3 scenarios when doing that:
1. Commit creating state vs. commit reusing state. If the commit creating the state went first, we would have to retry the commit reusing the state (to make sure we're reusing the new state). If the commit reusing the state went first, we wouldn't have conflicts, and we would just apply the new state on top of it. {F1061617730}
2. Commit reusing state vs. another commit reusing state. In this case the order doesn't matter and we don't need to trigger a conflict. Commits would be updated in the order in which they are applied. {F1061618406}
3. Commit creating state vs. commit creating state. In this case, we are not propagating state, so retrying the commits wouldn't do anything. We can ignore the conflicts in this case too. {F1061618689}
Changelog: [internal]
Reviewed By: sammy-SC
Differential Revision: D47915384
fbshipit-source-id: bb4510c59bf32ca342c02f3bdb7029b545f56d99
Co-authored-by: Samuel Susla <samuel.susla@gmail.com>
Co-authored-by: David Vacca
Co-authored-by: Tomek Zawadzki <tomasz.zawadzki@swmansion.com>
Co-authored-by: Krzysztof Piaskowy <krzysztof.piaskowy@swmansion.com>
Summary:
This change stores artifacts in CI only when it runs in main or in a stable branch
## Changelog:
[Internal] - Store CI artifacts only on main or on stable branches
Pull Request resolved: https://github.com/facebook/react-native/pull/38954
Test Plan: CircleCI stays green and we don't store anything on pr branch
Reviewed By: cortinico
Differential Revision: D48267659
Pulled By: cipolleschi
fbshipit-source-id: 6257270948c770e09492691c995cbe84d7a085ac
Summary:
Adds changelog for the 0.72.4 patch.
## Changelog:
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal] [Changed] - Add 0.72.4 changelog
Pull Request resolved: https://github.com/facebook/react-native/pull/38986
Reviewed By: cipolleschi
Differential Revision: D48310875
Pulled By: huntie
fbshipit-source-id: e7993ba28892b481aca3bad18479c870e659b007
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38886
This change introduces a property called `react.internal.useHermesNightly`
This allows users building RN-Tester or just ReactAndroid to fetch Hermes from the latest
nightly, without having to build it from source.
The change could be useful to speedup local development, but it should not be enabled on CI or when doing releases.
Changelog:
[Internal] [Changed] - Introduce react.internal.useHermesNightly
Reviewed By: mdvacca, cipolleschi
Differential Revision: D48188769
fbshipit-source-id: cb4330cb9082e9db0c7ba82e48b2d10030637353
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38924
## The Problem
We're currently compiling React Native with two JDK, 11 and 17.
This is necessary as we use PowerMock to mock static classes in our tests. PowerMock is effectively unmaintained and is preventing us from using only JDK 17.
Using two JDKs requires a bigger docker container and leads to build failures when contributors try to contribute to RN so we should be moving to use only a single JDK (also we can expect Google to bumpthe requirement to JDK 21 at some point in the future).
## The Solution
Practically, Mockito 3 offers the same capabilities that PowerMock offers.
I've removed PowerMock from our codebase and bumped Mockito to 3.
I've verified that all the un-ignored tests are green both with Gradle and Buck.
I've updated the Ignore-d tests to don't use PowerMock (as the project won't compile otherwise).
When we un-suppress them we will have to make sure everything works.
I've also left some TODOs referencing the old code for the future.
Changelog:
[Internal] [Changed] - Bump Mockito to 3.x and remove PowerMock
Reviewed By: cipolleschi
Differential Revision: D48228603
fbshipit-source-id: 5d4af902d813f347f19fc17361d53a73b685544d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38885
We do have several Gradle Properties that are used to configure the build.
I've refactored them all and moved them inside the PropertyUtils file:
https://github.com/facebook/react-native/blob/main/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt
Specifically properties should be 'scoped' under `react.` if public, and `react.internal.` if for internal usage.
Property that I cleaned up are:
- REACT_NATIVE_MAVEN_LOCAL_REPO becomes react.internal.mavenLocalRepo
- REACT_WINDOWS_BASH becomes react.internal.windowsBashPath
- GROUP becomes react.internal.publishingGroup
I've also added support for scoping for public properties with backward compat (so both the scoped and unscoped properties are accepted):
- react.newArchEnabled
- react.hermesEnabled
- react.nativeArchitectures
Changelog:
[Android] [Changed] - Cleanup and scope all the Gradle Properties
Reviewed By: mdvacca
Differential Revision: D48188310
fbshipit-source-id: 1a92d31105270a4c2f80029b7d36bcb33916d0fb
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38973
Original commit changeset: 6c00c2fcfdfd
Original Phabricator Diff: D47852371
When #38674 and #38959 are combined, they cause Android apps on Fabric to crash. #38959 is the more urgent fix, so backing out #38674.
## Changelog:
[General] [Fixed] - Rolling back change that broke e2e tests until we can figure out why the e2e tests are broken
Reviewed By: NickGerleman
Differential Revision: D48288752
fbshipit-source-id: b52e28936bbebd21bd3b2f49f9a233f295ba6248
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38968
A previous change introduced a bug where elevation was no longer being parsed on Android, which caused views that were previously flattened to no longer get flattened. This is a hotfix that could be pushed to affected builds without native code changes, but will not restore the shadow UX.
## Changelog:
[General] [Internal] - Internal
Reviewed By: bvanderhoof
Differential Revision: D48271545
fbshipit-source-id: ebbecd8073a074525ff7b95a6298612d0bb304c6
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38940
## Changelog:
[Internal] - make notch detection more future proof
current implementation of `isIPhoneX_deprecated` is not completely correct and is already 2 iphones behind. i update the implementation so we don't have to change it with every new iphone that comes out.
Reviewed By: cipolleschi
Differential Revision: D48254737
fbshipit-source-id: a7f45d70b06ab6c6d4fe036885c8a623fed0958e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38969
As we migrate java to kotlin I noticed that we've introduced few warnings here and there.
In this diff I'm enabling allWarningsAsErrors in the CI
The reasoning is that we are just starting with Kotlin and I believe we should enable 'allWarningsAsErrors' for CI android builds to make sure the codebase grow healthy, this will also help us to cleanup apis. e.g. create APIs for
deprecated java APIs.
changelog: [internal] internal
Reviewed By: NickGerleman
Differential Revision: D48239603
fbshipit-source-id: dd7a5df98cea82bf9bab6b26c4b1baa9f743ccbf
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38962
Changelog: [General][Changed] Math.floor the top and bottom dimensions of a cell item when determining viewability.
Reviewed By: NickGerleman
Differential Revision: D48212402
fbshipit-source-id: 0ba7d5c218477c257a4504391940d916e4832f91
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38674
Changelog: [Internal] - Refactor conditional pointer event emitting to the C++ layer
Some background: early on in the implementation of Pointer Events a concern was brought up that events related to hovering pointers could saturate the JS thread if they were fired all the time unconditionally, so as a mitigation we would check in native to see if listeners in the tree were listening for those events and only fire them if there were listeners.
Now since we're going to be moving some of the event derivation logic to the C++ layer we need to receive all the events — but recreate the conditional firing in the C++ layer so we can still avoid saturating the JS thread. That's what this diff does.
The only change I see being potentially contraversial is the fact that I needed a way to turn an `EventTarget` (the only information I receive regarding which node the event is firing on) to its cooresponding `ShadowNode` which I did in the method `GetShadowNodeFromEventTarget`. It essentially does the exact same thing the `getNodeFromInternalInstanceHandle` method in `ReactNativePublicCompat.js`, but in C++ against the JSI API. I don't know if there's a better way to do this but this was the best one I came up with that actually works.
Reviewed By: NickGerleman
Differential Revision: D47852371
fbshipit-source-id: 6c00c2fcfdfd49314c96d044d36272e028e074ff
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38955
Jest introduced "modern" timers based on `sinon/fake-timers` in Jest 26 ([release announcement](https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers)), and they became the default in Jest 27, in May 2021.
Modern timers have more capabilities - they were introduced with support for `queueMicrotask`, mocking `Date`, etc., and they've continued to receive more attention from the Jest team since - they're now much more comprehensive and more configurable than legacy timers.
Importantly, because they're not based on Jest mocks, they're not affected in surprising ways by eg `jest.resetAllMocks()` (a particularly confusing side-effect when fake timers are enabled globally, as in our setup).
This migrates RN's own tests and config to modern fake timers, or real timers where that's more appropriate.
NOTE: In cases where non-trivial changes to the tests are required, four test files are individually opted-in to `legacyFakeTimers` with a `TODO(legacy-fake-timers)`. I'll open these up for community contributions to fix.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D48189907
fbshipit-source-id: 2e7ce74cc60e80679d81d7c16d599ad1bbe2c921
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38945
Another pass of moving version numbers into a single place.
This time I've moved all the native dependencies from gradle.properties to the version catalog
Changelog:
[Internal] [Changed] - Consoliate Native deps version inside the Version Catalog
Reviewed By: cipolleschi
Differential Revision: D48263910
fbshipit-source-id: 0743908282dc658e2da347052e3b721704859f12
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38949
I've done another pass and moved all the compileSdk/minSdk/targetSdk and buildToolVersion in a single place so that we can easily bump one for all the projects.
Changelog:
[Internal] [Changed] - Consoliate Android SDK version inside the Version Catalog
Reviewed By: cipolleschi
Differential Revision: D48263891
fbshipit-source-id: bb9565cded37bae986865f37f4891575396128d0
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38946
I'm doing another pass of moving all the various version numbers of the Gradle Plugin inside the `[plugins]` section of the version catalog.
Changelog:
[Internal] [Changed] - Consolidate Gradle Plugin versions inside the version catalog
Reviewed By: mdvacca
Differential Revision: D48233147
fbshipit-source-id: afd12e5377d2d88c53cef4e6913b5c49b3da5bbb
Summary:
Removing the `test_ios_rntester` jobs for the following config:
- (OldArch, JSC, StaticLibraries)
- (OldArch, Hermes, StaticLibraries)
As this job just test that this configuration can be built and we have two other jobs (`test_ios-Hermes` and `test_ios-JSC`) which builds the same configs (so the test is duplicated) and they run unit and integration tests on top of these.
bypass-github-export-checks
## Changelog:
[Internal] - Remove duplicated `test_ios_rntester` jobs
Reviewed By: cortinico
Differential Revision: D48264664
fbshipit-source-id: 6dbf0edb9aba9ca8340b7c722b4f5c189c961577
Summary:
Migrate MyNativeViewManager to kotlin as part of ☂️https://github.com/facebook/react-native/issues/38825
## Changelog:
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal][Changed]: Migrate MyNativeViewManager to kotlin
Pull Request resolved: https://github.com/facebook/react-native/pull/38916
Test Plan: Verify RN Tester runs with `yarn android`
Reviewed By: cortinico, NickGerleman
Differential Revision: D48221141
Pulled By: mdvacca
fbshipit-source-id: 1cc5dc4346f265883e79893b69f0da5e8c632f2a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38927
I've done a pass and fixed most of the warnings for Gradle 9:
- project.buildDir is deprecated in favor of project.layout.buildDirectory
- I've updated 3rd party Gradle Plugins that we depend on
There are still two warnings which are outside of our control:
1. One is inside AGP and will be fixed with AGP 8.2 - Source https://issuetracker.google.com/issues/279306626
2. Another one is inside nexus-publish and should ideally be fixed by 2.0 https://github.com/gradle/gradle/issues/25206 Will bump the release once it's out
Changelog:
[Internal] [Changed] - Fix warnings for Gradle 9
Reviewed By: mdvacca
Differential Revision: D48231760
fbshipit-source-id: 27d704324ea33cfc8aa0164fa437b80aab425960
Summary:
Removing this job as the e2e test does basically the same work and run some e2e tests on top of that.
bypass-github-export-checks
## Changelog:
[Internal] - Remove Xcode<-->Hermes integration as it is dupicated by the e2e_ios
Reviewed By: cortinico
Differential Revision: D48229891
fbshipit-source-id: dbc8ef0f62c8839773232d5b07385b1006c601ce
Summary:
CircleCI is broken because we deleted a command but forgot to remove one last usage of it.
bypass-github-export-checks
## Changelog:
[Internal] - Remove last usage of setup_artifacts
Pull Request resolved: https://github.com/facebook/react-native/pull/38943
Test Plan: CircleCI is green
Reviewed By: Andjeliko, rshest, GijsWeterings
Differential Revision: D48263252
Pulled By: cipolleschi
fbshipit-source-id: 2f169952479389e476dfab0f88474c759728d3b4
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38901
This step is really necessary or if the folders will be created on the fly.
Changelog:
[Internal] [Changed] - Remove setup_artifacts as unnecessary
Reviewed By: mdvacca
Differential Revision: D48197595
fbshipit-source-id: ed2455dfdb9dcb4ce9219fc27d496d6faca4ddc2