@wordpress/data
Advanced tools
Comparing version 9.5.0 to 9.5.1
@@ -1,2 +0,1 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import { createElement } from "@wordpress/element"; | ||
@@ -101,3 +100,5 @@ | ||
const dispatchProps = useDispatchWithMap(mapDispatch, []); | ||
return createElement(WrappedComponent, _extends({}, ownProps, dispatchProps)); | ||
return createElement(WrappedComponent, { ...ownProps, | ||
...dispatchProps | ||
}); | ||
}, 'withDispatch'); | ||
@@ -104,0 +105,0 @@ |
@@ -1,2 +0,1 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import { createElement } from "@wordpress/element"; | ||
@@ -22,6 +21,6 @@ | ||
const withRegistry = createHigherOrderComponent(OriginalComponent => props => createElement(RegistryConsumer, null, registry => createElement(OriginalComponent, _extends({}, props, { | ||
const withRegistry = createHigherOrderComponent(OriginalComponent => props => createElement(RegistryConsumer, null, registry => createElement(OriginalComponent, { ...props, | ||
registry: registry | ||
}))), 'withRegistry'); | ||
})), 'withRegistry'); | ||
export default withRegistry; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,1 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import { createElement } from "@wordpress/element"; | ||
@@ -60,3 +59,5 @@ | ||
const mergeProps = useSelect(mapSelect); | ||
return createElement(WrappedComponent, _extends({}, ownProps, mergeProps)); | ||
return createElement(WrappedComponent, { ...ownProps, | ||
...mergeProps | ||
}); | ||
}), 'withSelect'); | ||
@@ -63,0 +64,0 @@ |
@@ -48,3 +48,3 @@ /** | ||
* Flag indicating that the selector is a registry selector that needs the correct registry | ||
* reference to be assigned to `selecto.registry` to make it work correctly. | ||
* reference to be assigned to `selector.registry` to make it work correctly. | ||
* be mapped as a registry selector. | ||
@@ -51,0 +51,0 @@ * |
@@ -18,3 +18,3 @@ /** | ||
import { builtinControls } from '../controls'; | ||
import { lock } from '../private-apis'; | ||
import { lock } from '../lock-unlock'; | ||
import promise from '../promise-middleware'; | ||
@@ -101,2 +101,19 @@ import createResolversCacheMiddleware from '../resolvers-cache-middleware'; | ||
} | ||
function createBindingCache(bind) { | ||
const cache = new WeakMap(); | ||
return { | ||
get(item) { | ||
let boundItem = cache.get(item); | ||
if (!boundItem) { | ||
boundItem = bind(item); | ||
cache.set(item, boundItem); | ||
} | ||
return boundItem; | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -151,7 +168,7 @@ * Creates a data store descriptor for the provided Redux store configuration containing | ||
get dispatch() { | ||
return Object.assign(action => store.dispatch(action), getActions()); | ||
return thunkActions; | ||
}, | ||
get select() { | ||
return Object.assign(selector => selector(store.__unstableOriginalGetState()), getSelectors()); | ||
return thunkSelectors; | ||
}, | ||
@@ -177,8 +194,13 @@ | ||
}; | ||
lock(actions, new Proxy(privateActions, { | ||
const boundPrivateActions = createBindingCache(bindAction); | ||
const allActions = new Proxy(() => {}, { | ||
get: (target, prop) => { | ||
const privateAction = privateActions[prop]; | ||
return privateAction ? bindAction(privateAction) : actions[prop]; | ||
return privateAction ? boundPrivateActions.get(privateAction) : actions[prop]; | ||
} | ||
})); | ||
}); | ||
const thunkActions = new Proxy(allActions, { | ||
apply: (target, thisArg, [action]) => store.dispatch(action) | ||
}); | ||
lock(actions, allActions); | ||
@@ -221,8 +243,19 @@ function bindSelector(selector) { | ||
lock(selectors, new Proxy(privateSelectors, { | ||
const boundPrivateSelectors = createBindingCache(bindSelector); // Pre-bind the private selectors that have been registered by the time of | ||
// instantiation, so that registry selectors are bound to the registry. | ||
for (const privateSelector of Object.values(privateSelectors)) { | ||
boundPrivateSelectors.get(privateSelector); | ||
} | ||
const allSelectors = new Proxy(() => {}, { | ||
get: (target, prop) => { | ||
const privateSelector = privateSelectors[prop]; | ||
return privateSelector ? bindSelector(privateSelector) : selectors[prop]; | ||
return privateSelector ? boundPrivateSelectors.get(privateSelector) : selectors[prop]; | ||
} | ||
})); | ||
}); | ||
const thunkSelectors = new Proxy(allSelectors, { | ||
apply: (target, thisArg, [selector]) => selector(store.__unstableOriginalGetState()) | ||
}); | ||
lock(selectors, allSelectors); | ||
const resolveSelectors = mapResolveSelectors(selectors, store); | ||
@@ -229,0 +262,0 @@ const suspendSelectors = mapSuspendSelectors(selectors, store); |
@@ -12,3 +12,3 @@ /** | ||
import { createEmitter } from './utils/emitter'; | ||
import { lock, unlock } from './private-apis'; | ||
import { lock, unlock } from './lock-unlock'; | ||
/** @typedef {import('./types').StoreDescriptor} StoreDescriptor */ | ||
@@ -15,0 +15,0 @@ |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -12,4 +10,2 @@ value: true | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _compose = require("@wordpress/compose"); | ||
@@ -114,3 +110,5 @@ | ||
const dispatchProps = (0, _useDispatch.useDispatchWithMap)(mapDispatch, []); | ||
return (0, _element.createElement)(WrappedComponent, (0, _extends2.default)({}, ownProps, dispatchProps)); | ||
return (0, _element.createElement)(WrappedComponent, { ...ownProps, | ||
...dispatchProps | ||
}); | ||
}, 'withDispatch'); | ||
@@ -117,0 +115,0 @@ |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -12,4 +10,2 @@ value: true | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _compose = require("@wordpress/compose"); | ||
@@ -35,7 +31,7 @@ | ||
*/ | ||
const withRegistry = (0, _compose.createHigherOrderComponent)(OriginalComponent => props => (0, _element.createElement)(_registryProvider.RegistryConsumer, null, registry => (0, _element.createElement)(OriginalComponent, (0, _extends2.default)({}, props, { | ||
const withRegistry = (0, _compose.createHigherOrderComponent)(OriginalComponent => props => (0, _element.createElement)(_registryProvider.RegistryConsumer, null, registry => (0, _element.createElement)(OriginalComponent, { ...props, | ||
registry: registry | ||
}))), 'withRegistry'); | ||
})), 'withRegistry'); | ||
var _default = withRegistry; | ||
exports.default = _default; | ||
//# sourceMappingURL=index.js.map |
@@ -12,4 +12,2 @@ "use strict"; | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _compose = require("@wordpress/compose"); | ||
@@ -73,3 +71,5 @@ | ||
const mergeProps = (0, _useSelect.default)(mapSelect); | ||
return (0, _element.createElement)(WrappedComponent, (0, _extends2.default)({}, ownProps, mergeProps)); | ||
return (0, _element.createElement)(WrappedComponent, { ...ownProps, | ||
...mergeProps | ||
}); | ||
}), 'withSelect'); | ||
@@ -76,0 +76,0 @@ |
@@ -56,3 +56,3 @@ "use strict"; | ||
* Flag indicating that the selector is a registry selector that needs the correct registry | ||
* reference to be assigned to `selecto.registry` to make it work correctly. | ||
* reference to be assigned to `selector.registry` to make it work correctly. | ||
* be mapped as a registry selector. | ||
@@ -59,0 +59,0 @@ * |
@@ -22,3 +22,3 @@ "use strict"; | ||
var _privateApis = require("../private-apis"); | ||
var _lockUnlock = require("../lock-unlock"); | ||
@@ -127,2 +127,19 @@ var _promiseMiddleware = _interopRequireDefault(require("../promise-middleware")); | ||
} | ||
function createBindingCache(bind) { | ||
const cache = new WeakMap(); | ||
return { | ||
get(item) { | ||
let boundItem = cache.get(item); | ||
if (!boundItem) { | ||
boundItem = bind(item); | ||
cache.set(item, boundItem); | ||
} | ||
return boundItem; | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -177,7 +194,7 @@ * Creates a data store descriptor for the provided Redux store configuration containing | ||
get dispatch() { | ||
return Object.assign(action => store.dispatch(action), getActions()); | ||
return thunkActions; | ||
}, | ||
get select() { | ||
return Object.assign(selector => selector(store.__unstableOriginalGetState()), getSelectors()); | ||
return thunkSelectors; | ||
}, | ||
@@ -193,3 +210,3 @@ | ||
(0, _privateApis.lock)(store, privateRegistrationFunctions); | ||
(0, _lockUnlock.lock)(store, privateRegistrationFunctions); | ||
const resolversCache = createResolversCache(); | ||
@@ -204,8 +221,13 @@ | ||
}; | ||
(0, _privateApis.lock)(actions, new Proxy(privateActions, { | ||
const boundPrivateActions = createBindingCache(bindAction); | ||
const allActions = new Proxy(() => {}, { | ||
get: (target, prop) => { | ||
const privateAction = privateActions[prop]; | ||
return privateAction ? bindAction(privateAction) : actions[prop]; | ||
return privateAction ? boundPrivateActions.get(privateAction) : actions[prop]; | ||
} | ||
})); | ||
}); | ||
const thunkActions = new Proxy(allActions, { | ||
apply: (target, thisArg, [action]) => store.dispatch(action) | ||
}); | ||
(0, _lockUnlock.lock)(actions, allActions); | ||
@@ -248,8 +270,19 @@ function bindSelector(selector) { | ||
(0, _privateApis.lock)(selectors, new Proxy(privateSelectors, { | ||
const boundPrivateSelectors = createBindingCache(bindSelector); // Pre-bind the private selectors that have been registered by the time of | ||
// instantiation, so that registry selectors are bound to the registry. | ||
for (const privateSelector of Object.values(privateSelectors)) { | ||
boundPrivateSelectors.get(privateSelector); | ||
} | ||
const allSelectors = new Proxy(() => {}, { | ||
get: (target, prop) => { | ||
const privateSelector = privateSelectors[prop]; | ||
return privateSelector ? bindSelector(privateSelector) : selectors[prop]; | ||
return privateSelector ? boundPrivateSelectors.get(privateSelector) : selectors[prop]; | ||
} | ||
})); | ||
}); | ||
const thunkSelectors = new Proxy(allSelectors, { | ||
apply: (target, thisArg, [selector]) => selector(store.__unstableOriginalGetState()) | ||
}); | ||
(0, _lockUnlock.lock)(selectors, allSelectors); | ||
const resolveSelectors = mapResolveSelectors(selectors, store); | ||
@@ -309,3 +342,3 @@ const suspendSelectors = mapSuspendSelectors(selectors, store); | ||
(0, _privateApis.lock)(storeDescriptor, privateRegistrationFunctions); | ||
(0, _lockUnlock.lock)(storeDescriptor, privateRegistrationFunctions); | ||
return storeDescriptor; | ||
@@ -312,0 +345,0 @@ } |
@@ -18,3 +18,3 @@ "use strict"; | ||
var _privateApis = require("./private-apis"); | ||
var _lockUnlock = require("./lock-unlock"); | ||
@@ -287,4 +287,4 @@ /** | ||
try { | ||
(0, _privateApis.unlock)(store.store).registerPrivateActions((0, _privateApis.unlock)(parent).privateActionsOf(name)); | ||
(0, _privateApis.unlock)(store.store).registerPrivateSelectors((0, _privateApis.unlock)(parent).privateSelectorsOf(name)); | ||
(0, _lockUnlock.unlock)(store.store).registerPrivateActions((0, _lockUnlock.unlock)(parent).privateActionsOf(name)); | ||
(0, _lockUnlock.unlock)(store.store).registerPrivateSelectors((0, _lockUnlock.unlock)(parent).privateSelectorsOf(name)); | ||
} catch (e) {// unlock() throws if store.store was not locked. | ||
@@ -384,6 +384,6 @@ // The error indicates there's nothing to do here so let's | ||
const registryWithPlugins = withPlugins(registry); | ||
(0, _privateApis.lock)(registryWithPlugins, { | ||
(0, _lockUnlock.lock)(registryWithPlugins, { | ||
privateActionsOf: name => { | ||
try { | ||
return (0, _privateApis.unlock)(stores[name].store).privateActions; | ||
return (0, _lockUnlock.unlock)(stores[name].store).privateActions; | ||
} catch (e) { | ||
@@ -397,3 +397,3 @@ // unlock() throws an error the store was not locked – this means | ||
try { | ||
return (0, _privateApis.unlock)(stores[name].store).privateSelectors; | ||
return (0, _lockUnlock.unlock)(stores[name].store).privateSelectors; | ||
} catch (e) { | ||
@@ -400,0 +400,0 @@ return {}; |
{ | ||
"name": "@wordpress/data", | ||
"version": "9.5.0", | ||
"version": "9.5.1", | ||
"description": "Data module for WordPress.", | ||
@@ -32,9 +32,9 @@ "author": "The WordPress Contributors", | ||
"@babel/runtime": "^7.16.0", | ||
"@wordpress/compose": "^6.12.0", | ||
"@wordpress/deprecated": "^3.35.0", | ||
"@wordpress/element": "^5.12.0", | ||
"@wordpress/is-shallow-equal": "^4.35.0", | ||
"@wordpress/priority-queue": "^2.35.0", | ||
"@wordpress/private-apis": "^0.17.0", | ||
"@wordpress/redux-routine": "^4.35.0", | ||
"@wordpress/compose": "^6.12.1", | ||
"@wordpress/deprecated": "^3.35.1", | ||
"@wordpress/element": "^5.12.1", | ||
"@wordpress/is-shallow-equal": "^4.35.1", | ||
"@wordpress/priority-queue": "^2.35.1", | ||
"@wordpress/private-apis": "^0.17.1", | ||
"@wordpress/redux-routine": "^4.35.1", | ||
"deepmerge": "^4.3.0", | ||
@@ -54,3 +54,3 @@ "equivalent-key-map": "^0.2.2", | ||
}, | ||
"gitHead": "a92f606309b1541b834ff9b0a76ed2a466fc45ed" | ||
"gitHead": "ce5639111c30763dbdf07f40eeb136ea6030ecf1" | ||
} |
@@ -50,3 +50,3 @@ /** | ||
* Flag indicating that the selector is a registry selector that needs the correct registry | ||
* reference to be assigned to `selecto.registry` to make it work correctly. | ||
* reference to be assigned to `selector.registry` to make it work correctly. | ||
* be mapped as a registry selector. | ||
@@ -53,0 +53,0 @@ * |
@@ -18,3 +18,3 @@ /** | ||
import { builtinControls } from '../controls'; | ||
import { lock } from '../private-apis'; | ||
import { lock } from '../lock-unlock'; | ||
import promise from '../promise-middleware'; | ||
@@ -105,2 +105,17 @@ import createResolversCacheMiddleware from '../resolvers-cache-middleware'; | ||
function createBindingCache( bind ) { | ||
const cache = new WeakMap(); | ||
return { | ||
get( item ) { | ||
let boundItem = cache.get( item ); | ||
if ( ! boundItem ) { | ||
boundItem = bind( item ); | ||
cache.set( item, boundItem ); | ||
} | ||
return boundItem; | ||
}, | ||
}; | ||
} | ||
/** | ||
@@ -152,13 +167,6 @@ * Creates a data store descriptor for the provided Redux store configuration containing | ||
get dispatch() { | ||
return Object.assign( | ||
( action ) => store.dispatch( action ), | ||
getActions() | ||
); | ||
return thunkActions; | ||
}, | ||
get select() { | ||
return Object.assign( | ||
( selector ) => | ||
selector( store.__unstableOriginalGetState() ), | ||
getSelectors() | ||
); | ||
return thunkSelectors; | ||
}, | ||
@@ -191,14 +199,19 @@ get resolveSelect() { | ||
lock( | ||
actions, | ||
new Proxy( privateActions, { | ||
get: ( target, prop ) => { | ||
const privateAction = privateActions[ prop ]; | ||
return privateAction | ||
? bindAction( privateAction ) | ||
: actions[ prop ]; | ||
}, | ||
} ) | ||
); | ||
const boundPrivateActions = createBindingCache( bindAction ); | ||
const allActions = new Proxy( () => {}, { | ||
get: ( target, prop ) => { | ||
const privateAction = privateActions[ prop ]; | ||
return privateAction | ||
? boundPrivateActions.get( privateAction ) | ||
: actions[ prop ]; | ||
}, | ||
} ); | ||
const thunkActions = new Proxy( allActions, { | ||
apply: ( target, thisArg, [ action ] ) => | ||
store.dispatch( action ), | ||
} ); | ||
lock( actions, allActions ); | ||
function bindSelector( selector ) { | ||
@@ -241,14 +254,26 @@ if ( selector.isRegistrySelector ) { | ||
lock( | ||
selectors, | ||
new Proxy( privateSelectors, { | ||
get: ( target, prop ) => { | ||
const privateSelector = privateSelectors[ prop ]; | ||
return privateSelector | ||
? bindSelector( privateSelector ) | ||
: selectors[ prop ]; | ||
}, | ||
} ) | ||
); | ||
const boundPrivateSelectors = createBindingCache( bindSelector ); | ||
// Pre-bind the private selectors that have been registered by the time of | ||
// instantiation, so that registry selectors are bound to the registry. | ||
for ( const privateSelector of Object.values( privateSelectors ) ) { | ||
boundPrivateSelectors.get( privateSelector ); | ||
} | ||
const allSelectors = new Proxy( () => {}, { | ||
get: ( target, prop ) => { | ||
const privateSelector = privateSelectors[ prop ]; | ||
return privateSelector | ||
? boundPrivateSelectors.get( privateSelector ) | ||
: selectors[ prop ]; | ||
}, | ||
} ); | ||
const thunkSelectors = new Proxy( allSelectors, { | ||
apply: ( target, thisArg, [ selector ] ) => | ||
selector( store.__unstableOriginalGetState() ), | ||
} ); | ||
lock( selectors, allSelectors ); | ||
const resolveSelectors = mapResolveSelectors( selectors, store ); | ||
@@ -255,0 +280,0 @@ const suspendSelectors = mapSuspendSelectors( selectors, store ); |
@@ -12,3 +12,3 @@ /** | ||
import { createEmitter } from './utils/emitter'; | ||
import { lock, unlock } from './private-apis'; | ||
import { lock, unlock } from './lock-unlock'; | ||
@@ -15,0 +15,0 @@ /** @typedef {import('./types').StoreDescriptor} StoreDescriptor */ |
@@ -6,3 +6,4 @@ /** | ||
import createReduxStore from '../redux-store'; | ||
import { unlock } from '../private-apis'; | ||
import { unlock } from '../lock-unlock'; | ||
import { createRegistrySelector } from '../factory'; | ||
@@ -36,19 +37,15 @@ describe( 'Private data APIs', () => { | ||
actions: { setPublicPrice }, | ||
reducer: ( state, action ) => { | ||
if ( action?.type === 'SET_PRIVATE_PRICE' ) { | ||
reducer: ( state = { price: 1000, secretDiscount: 800 }, action ) => { | ||
if ( action.type === 'SET_PRIVATE_PRICE' ) { | ||
return { | ||
...state, | ||
secretDiscount: action?.price, | ||
secretDiscount: action.price, | ||
}; | ||
} else if ( action?.type === 'SET_PUBLIC_PRICE' ) { | ||
} else if ( action.type === 'SET_PUBLIC_PRICE' ) { | ||
return { | ||
...state, | ||
price: action?.price, | ||
price: action.price, | ||
}; | ||
} | ||
return { | ||
price: 1000, | ||
secretDiscount: 800, | ||
...( state || {} ), | ||
}; | ||
return state; | ||
}, | ||
@@ -152,2 +149,12 @@ }; | ||
it( 'should return stable references to selectors', () => { | ||
const groceryStore = createStore(); | ||
unlock( groceryStore ).registerPrivateSelectors( { | ||
getSecretDiscount, | ||
} ); | ||
const select = unlock( registry.select( groceryStore ) ); | ||
expect( select.getPublicPrice ).toBe( select.getPublicPrice ); | ||
expect( select.getSecretDiscount ).toBe( select.getSecretDiscount ); | ||
} ); | ||
it( 'should support registerStore', () => { | ||
@@ -201,2 +208,38 @@ const groceryStore = registry.registerStore( | ||
} ); | ||
it( 'should support private registry selectors', () => { | ||
const groceryStore = createStore(); | ||
const otherStore = createReduxStore( 'other', { | ||
reducer: ( state = {} ) => state, | ||
} ); | ||
unlock( otherStore ).registerPrivateSelectors( { | ||
getPrice: createRegistrySelector( | ||
( select ) => () => select( groceryStore ).getPublicPrice() | ||
), | ||
} ); | ||
registry.register( otherStore ); | ||
const privateSelectors = unlock( registry.select( otherStore ) ); | ||
expect( privateSelectors.getPrice() ).toEqual( 1000 ); | ||
} ); | ||
it( 'should support calling a private registry selector from a public selector', () => { | ||
const groceryStore = createStore(); | ||
const getPriceWithShipping = createRegistrySelector( | ||
( select ) => () => select( groceryStore ).getPublicPrice() + 5 | ||
); | ||
const store = createReduxStore( 'a', { | ||
reducer: ( state = {} ) => state, | ||
selectors: { | ||
getPriceWithShippingAndTax: ( state ) => | ||
getPriceWithShipping( state ) * 1.1, | ||
}, | ||
} ); | ||
unlock( store ).registerPrivateSelectors( { | ||
getPriceWithShipping, | ||
} ); | ||
registry.register( store ); | ||
expect( | ||
registry.select( store ).getPriceWithShippingAndTax() | ||
).toEqual( 1105.5 ); | ||
} ); | ||
} ); | ||
@@ -270,2 +313,12 @@ | ||
it( 'should return stable references to actions', () => { | ||
const groceryStore = createStore(); | ||
unlock( groceryStore ).registerPrivateActions( { | ||
setSecretDiscount, | ||
} ); | ||
const disp = unlock( registry.dispatch( groceryStore ) ); | ||
expect( disp.setPublicPrice ).toBe( disp.setPublicPrice ); | ||
expect( disp.setSecretDiscount ).toBe( disp.setSecretDiscount ); | ||
} ); | ||
it( 'should dispatch public actions on the unlocked store', () => { | ||
@@ -302,2 +355,25 @@ const groceryStore = createStore(); | ||
it( 'should expose unlocked private selectors and actions to thunks', () => { | ||
const groceryStore = createStore(); | ||
unlock( groceryStore ).registerPrivateSelectors( { | ||
getSecretDiscount, | ||
} ); | ||
unlock( groceryStore ).registerPrivateActions( { | ||
setSecretDiscount, | ||
doubleSecretDiscount() { | ||
return ( { dispatch, select } ) => { | ||
dispatch.setSecretDiscount( | ||
select.getSecretDiscount() * 2 | ||
); | ||
}; | ||
}, | ||
} ); | ||
const privateActions = unlock( registry.dispatch( groceryStore ) ); | ||
privateActions.setSecretDiscount( 100 ); | ||
privateActions.doubleSecretDiscount(); | ||
expect( | ||
unlock( registry.select( groceryStore ) ).getSecretDiscount() | ||
).toEqual( 200 ); | ||
} ); | ||
it( 'should support registerStore', () => { | ||
@@ -304,0 +380,0 @@ const groceryStore = registry.registerStore( |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
973988
14860