Commit 3af61a1b authored by Phạm Quang Bảo's avatar Phạm Quang Bảo

Merge branch 'develop-news' into 'release'

Develop news

See merge request !111
parents e62712af 337f3bdb
Pipeline #52980 passed with stages
in 9 seconds

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

import type { NextConfig } from "next"; import type { NextConfig } from "next";
import links from "./src/links/index";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
images: { images: {
remotePatterns: [ remotePatterns: [
...(links.backendHost
? [
{
protocol: links.backendProtocol as "http" | "https",
hostname: links.backendHost,
port: "",
pathname: `${links.backendPathname === "/" ? "" : links.backendPathname}/**`,
},
]
: []),
// Local development
{ {
protocol: "http", protocol: "http",
hostname: "localhost", hostname: "localhost",
...@@ -23,7 +11,7 @@ const nextConfig: NextConfig = { ...@@ -23,7 +11,7 @@ const nextConfig: NextConfig = {
}, },
{ {
protocol: "https", protocol: "https",
hostname: "vcci-hcm.org.vn", // WordPress / media host hostname: "vcci-hcm.org.vn",
port: "", port: "",
pathname: "/wp-content/uploads/**", pathname: "/wp-content/uploads/**",
}, },
......
This diff is collapsed.
import 'dotenv/config'
import { defineConfig } from "orval"; import { defineConfig } from "orval";
import axios from "axios"; import links from "./src/links/index";
import fs from "fs";
import path from "path"; const orvalConfig = defineConfig({
// VCCI News API
function loadEnvFile(filePath: string) { "vcci-news": {
if (!fs.existsSync(filePath)) return; output: {
mode: "tags",
const content = fs.readFileSync(filePath, "utf8"); target: "src/api/vcci-news/endpoints/index.ts",
content.split(/\r?\n/).forEach((line) => { schemas: "src/api/vcci-news/models",
const trimmed = line.trim(); client: "react-query",
if (!trimmed || trimmed.startsWith("#")) return; override: {
query: {
const equalsIndex = trimmed.indexOf("="); useInfinite: true,
if (equalsIndex < 0) return; usePrefetch: true,
options: {
const key = trimmed.slice(0, equalsIndex).trim(); retry: 3,
const value = trimmed.slice(equalsIndex + 1).trim().replace(/^['"]|['"]$/g, ""); retryDelay: 1000,
}
if (key && process.env[key] === undefined) { },
process.env[key] = value; mutator: {
} path: "src/api/vcci-news/mutator/custom-client.ts",
}); name: "useCustomClient",
} },
loadEnvFile(path.resolve(process.cwd(), ".env"));
const backendHost = process.env.NEXT_PUBLIC_BACKEND_HOST;
const siteURL = process.env.NEXT_PUBLIC_FRONTEND_HOST;
const swaggerCandidates = [
// 1) Explicit override (highest priority)
process.env.ORVAL_SWAGGER_URL,
// 2) Sibling backend repo (local dev with both repos checked out)
path.resolve(process.cwd(), "..", "vietprodev-cms-backend", "storage", "swagger", "swagger-output.json"),
// 3) Committed spec in repo — deterministic source for CI builds.
// Must be tried BEFORE HTTP URLs: production backend doesn't serve swagger
// and ${backendHost}/swagger/swagger-output.json may return a stale/wrong spec.
path.resolve(process.cwd(), "openapi", "swagger-output.json"),
// 4) HTTP fallbacks (last resort)
`${backendHost}/swagger-output.json`,
`${backendHost}/swagger/swagger-output.json`,
`${backendHost}/swagger.json`,
`${backendHost}/openapi.json`,
`${backendHost}/api/swagger/swagger-output.json`,
`${backendHost}/vcci/swagger/swagger-output.json`,
].filter(Boolean) as string[];
async function fetchSwagger() {
for (const url of swaggerCandidates) {
if (!url) continue;
// 1) Local file path
if (fs.existsSync(url) && fs.statSync(url).isFile()) {
const raw = fs.readFileSync(url, "utf8");
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`Swagger spec tại ${url} không phải JSON hợp lệ: ${error}`);
}
}
// 2) HTTP fetch — chỉ chấp nhận JSON, bỏ qua HTML (404, page app,...)
if (/^https?:\/\//i.test(url)) {
try {
const { data, headers } = await axios.get(url, {
headers: { Origin: siteURL },
// Ngăn axios tự nhận HTML là JSON — ép raw response để check Content-Type
responseType: "json",
validateStatus: (status) => status >= 200 && status < 400,
});
const contentType = String(headers?.["content-type"] ?? "").toLowerCase();
if (!contentType.includes("application/json") && typeof data === "string") {
// Phản hồi không phải JSON (thường là HTML 404) — bỏ qua candidate này
continue;
}
if (data && typeof data === "object") {
return data;
}
} catch {
continue;
} }
} },
} input: {
target: `${links.apiEndpoint}/swagger-output.json`,
// 3) Fallback cuối: openapi/swagger-output.json nằm trong repo filters: {
const localSwagger = path.resolve(process.cwd(), "openapi/swagger-output.json"); tags: undefined,
if (fs.existsSync(localSwagger)) {
const raw = fs.readFileSync(localSwagger, "utf8");
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`Swagger spec tại ${localSwagger} không phải JSON hợp lệ: ${error}`);
}
}
throw new Error(
`Unable to load Swagger/OpenAPI JSON. Tried: ${swaggerCandidates.join(", ")}`,
);
}
const orvalConfig = async () => {
const swagger = await fetchSwagger();
return defineConfig({
"saigon-business": {
output: {
mode: "tags",
target: "src/api/endpoints/index.ts",
schemas: "src/api/models",
client: "react-query",
prettier: true,
override: {
mutator: {
path: "src/api/mutator/custom-client.ts",
name: "useCustomClient",
},
query: {
useQuery: true,
useInfinite: true,
usePrefetch: true,
// useSuspenseQuery: true,
options: {
retry: 3,
retryDelay: 1000,
}
},
}
}, },
input: { },
target: swagger, },
filters: {
// Tag whitelist dùng tên CHÍNH XÁT trong OpenAPI spec — lấy từ openapi/swagger-output.json. // VCCI HCM API
// Cập nhật khi backend thêm/xóa tag. Bỏ hết filter nếu muốn generate toàn bộ. "vcci-hcm": {
tags: [ output: {
'Authentication', mode: "tags",
'Advertisement', target: "src/api/vcci-hcm/endpoints/index.ts",
'Banner', schemas: "src/api/vcci-hcm/models",
'Business', client: "react-query",
'Category', override: {
'CategoryTag', query: {
'Contact', useInfinite: true,
'File', usePrefetch: true,
'Logo', options: {
'Member', retry: 3,
'NewsletterSubscription', retryDelay: 1000,
'PageConfig', }
'PasswordResetRequest', },
'Permission', mutator: {
'Position', path: "src/api/vcci-hcm/mutator/custom-client.ts",
'Post', name: "useCustomClient",
'PostCategory',
'PostTag',
'Role',
'RolePermission',
'SiteInformation',
'Tag',
'Term',
'User',
'UserRole',
'VCCI',
'Video',
],
}, },
}
},
input: {
target: `${links.externalApiEndpoint}/swagger-output.json`,
validation: false,
parserOptions: { validate: false },
filters: {
tags: ["Organizations"],
}, },
}, },
}); }
} });
export default orvalConfig export default orvalConfig
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --webpack", "dev": "next dev --turbopack",
"build": "next build --webpack", "build": "next build --turbopack",
"start": "next start", "start": "next start",
"lint": "eslint", "lint": "eslint",
"generate:api": "node scripts/generate-api.mjs" "generate:api": "orval"
}, },
"dependencies": { "dependencies": {
"@hookform/resolvers": "^5.2.2", "@hookform/resolvers": "^5.2.2",
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
"jodit-react": "^5.3.21", "jodit-react": "^5.3.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lucide-react": "^0.548.0", "lucide-react": "^0.548.0",
"next": "16.0.10", "next": "16.2.10",
"next-nprogress-bar": "^2.4.7", "next-nprogress-bar": "^2.4.7",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "19.2.0", "react": "19.2.0",
...@@ -73,12 +73,13 @@ ...@@ -73,12 +73,13 @@
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"axios": "^1.13.1", "axios": "^1.13.1",
"baseline-browser-mapping": "^2.10.32", "baseline-browser-mapping": "^2.11.20",
"dotenv": "^17.4.2",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "16.0.1", "eslint-config-next": "16.0.1",
"orval": "8.0.0-rc.0", "orval": "^7.17.0",
"tailwindcss": "^4", "tailwindcss": "^4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5" "typescript": "^5"
} }
} }
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
const cwd = process.cwd();
const endpointsDir = path.join(cwd, "src", "api", "endpoints");
const modelsDir = path.join(cwd, "src", "api", "models");
function hasGeneratedApi() {
if (!fs.existsSync(endpointsDir) || !fs.existsSync(modelsDir)) {
return false;
}
const endpointFiles = fs.readdirSync(endpointsDir).filter((file) => file.endsWith(".ts"));
const modelFiles = fs.readdirSync(modelsDir).filter((file) => file.endsWith(".ts"));
return endpointFiles.length > 0 && modelFiles.length > 0;
}
const result = spawnSync(
process.platform === "win32" ? "npx.cmd" : "npx",
["orval", "-c", "orval.config.ts"],
{
cwd,
stdio: "inherit",
shell: false,
env: process.env,
},
);
if (result.status === 0) {
process.exit(0);
}
if (hasGeneratedApi()) {
console.warn(
"Skipping API regeneration because Swagger is unavailable and generated client files already exist.",
);
process.exit(0);
}
process.exit(result.status ?? 1);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Generated by orval v8.0.0-rc.0 🍺
* Do not edit manually.
* VietProDev CMS Backend API
* Generated API documentation
* OpenAPI spec version: 1.0.0
*/
import type { AdvertisementFile } from './advertisementFile';
import type { AdvertisementType } from './advertisementType';
import type { AdvertisementStatus } from './advertisementStatus';
export interface Advertisement {
id: string;
/** @maxLength 255 */
name: string;
file_id: string;
/** @nullable */
file?: AdvertisementFile;
/**
* @maxLength 255
* @nullable
*/
alt?: string | null;
/** @maxLength 500 */
link: string;
type: AdvertisementType;
status: AdvertisementStatus;
sort_order: number;
/** @nullable */
created_at?: string | null;
/** @nullable */
created_by?: string | null;
/** @nullable */
updated_at?: string | null;
/** @nullable */
updated_by?: string | null;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment