Configure remote database connection and update documentation

This commit is contained in:
Bivekich
2025-08-06 02:24:01 +03:00
parent 5bd7d79642
commit e1b79f017a
67 changed files with 1513 additions and 15 deletions

View File

@ -0,0 +1,2 @@
export declare class AuthModule {
}

View File

@ -0,0 +1,34 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthModule = void 0;
const common_1 = require("@nestjs/common");
const jwt_1 = require("@nestjs/jwt");
const passport_1 = require("@nestjs/passport");
const auth_service_1 = require("./auth.service");
const auth_resolver_1 = require("./auth.resolver");
const jwt_strategy_1 = require("./strategies/jwt.strategy");
const users_module_1 = require("../users/users.module");
let AuthModule = class AuthModule {
};
exports.AuthModule = AuthModule;
exports.AuthModule = AuthModule = __decorate([
(0, common_1.Module)({
imports: [
users_module_1.UsersModule,
passport_1.PassportModule,
jwt_1.JwtModule.register({
secret: process.env.JWT_SECRET || 'secret',
signOptions: { expiresIn: process.env.JWT_EXPIRATION || '7d' },
}),
],
providers: [auth_service_1.AuthService, auth_resolver_1.AuthResolver, jwt_strategy_1.JwtStrategy],
exports: [auth_service_1.AuthService],
})
], AuthModule);
//# sourceMappingURL=auth.module.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../../src/modules/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qCAAwC;AACxC,+CAAkD;AAClD,iDAA6C;AAC7C,mDAA+C;AAC/C,4DAAwD;AACxD,wDAAoD;AAc7C,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IAZtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,0BAAW;YACX,yBAAc;YACd,eAAS,CAAC,QAAQ,CAAC;gBACjB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,QAAQ;gBAC1C,WAAW,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,EAAE;aAC/D,CAAC;SACH;QACD,SAAS,EAAE,CAAC,0BAAW,EAAE,4BAAY,EAAE,0BAAW,CAAC;QACnD,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAAG"}

View File

@ -0,0 +1,14 @@
import { AuthService } from './auth.service';
import { User } from '../users/entities/user.entity';
export declare class AuthResolver {
private authService;
constructor(authService: AuthService);
login(username: string, password: string): Promise<{
access_token: string;
user: User;
}>;
register(username: string, email: string, password: string): Promise<{
access_token: string;
user: User;
}>;
}

View File

@ -0,0 +1,68 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthResolver = void 0;
const graphql_1 = require("@nestjs/graphql");
const auth_service_1 = require("./auth.service");
const user_entity_1 = require("../users/entities/user.entity");
let AuthResponse = class AuthResponse {
access_token;
user;
};
__decorate([
(0, graphql_1.Field)(),
__metadata("design:type", String)
], AuthResponse.prototype, "access_token", void 0);
__decorate([
(0, graphql_1.Field)(() => user_entity_1.User),
__metadata("design:type", user_entity_1.User)
], AuthResponse.prototype, "user", void 0);
AuthResponse = __decorate([
(0, graphql_1.ObjectType)()
], AuthResponse);
let AuthResolver = class AuthResolver {
authService;
constructor(authService) {
this.authService = authService;
}
async login(username, password) {
return this.authService.login(username, password);
}
async register(username, email, password) {
return this.authService.register(username, email, password);
}
};
exports.AuthResolver = AuthResolver;
__decorate([
(0, graphql_1.Mutation)(() => AuthResponse),
__param(0, (0, graphql_1.Args)('username')),
__param(1, (0, graphql_1.Args)('password')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String]),
__metadata("design:returntype", Promise)
], AuthResolver.prototype, "login", null);
__decorate([
(0, graphql_1.Mutation)(() => AuthResponse),
__param(0, (0, graphql_1.Args)('username')),
__param(1, (0, graphql_1.Args)('email')),
__param(2, (0, graphql_1.Args)('password')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String, String]),
__metadata("design:returntype", Promise)
], AuthResolver.prototype, "register", null);
exports.AuthResolver = AuthResolver = __decorate([
(0, graphql_1.Resolver)(),
__metadata("design:paramtypes", [auth_service_1.AuthService])
], AuthResolver);
//# sourceMappingURL=auth.resolver.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"auth.resolver.js","sourceRoot":"","sources":["../../../src/modules/auth/auth.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6CAA8E;AAC9E,iDAA6C;AAC7C,+DAAqD;AAGrD,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEhB,YAAY,CAAS;IAGrB,IAAI,CAAO;CACZ,CAAA;AAJC;IADC,IAAA,eAAK,GAAE;;kDACa;AAGrB;IADC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,kBAAI,CAAC;8BACZ,kBAAI;0CAAC;AALP,YAAY;IADjB,IAAA,oBAAU,GAAE;GACP,YAAY,CAMjB;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAY;IACH;IAApB,YAAoB,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAG1C,AAAN,KAAK,CAAC,KAAK,CACS,QAAgB,EAChB,QAAgB;QAElC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ,CACM,QAAgB,EACnB,KAAa,EACV,QAAgB;QAElC,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;CACF,CAAA;AAnBY,oCAAY;AAIjB;IADL,IAAA,kBAAQ,EAAC,GAAG,EAAE,CAAC,YAAY,CAAC;IAE1B,WAAA,IAAA,cAAI,EAAC,UAAU,CAAC,CAAA;IAChB,WAAA,IAAA,cAAI,EAAC,UAAU,CAAC,CAAA;;;;yCAGlB;AAGK;IADL,IAAA,kBAAQ,EAAC,GAAG,EAAE,CAAC,YAAY,CAAC;IAE1B,WAAA,IAAA,cAAI,EAAC,UAAU,CAAC,CAAA;IAChB,WAAA,IAAA,cAAI,EAAC,OAAO,CAAC,CAAA;IACb,WAAA,IAAA,cAAI,EAAC,UAAU,CAAC,CAAA;;;;4CAGlB;uBAlBU,YAAY;IADxB,IAAA,kBAAQ,GAAE;qCAEwB,0BAAW;GADjC,YAAY,CAmBxB"}

View File

@ -0,0 +1,17 @@
import { JwtService } from '@nestjs/jwt';
import { UsersService } from '../users/users.service';
import { User } from '../users/entities/user.entity';
export declare class AuthService {
private usersService;
private jwtService;
constructor(usersService: UsersService, jwtService: JwtService);
validateUser(username: string, password: string): Promise<User | null>;
login(username: string, password: string): Promise<{
access_token: string;
user: User;
}>;
register(username: string, email: string, password: string): Promise<{
access_token: string;
user: User;
}>;
}

View File

@ -0,0 +1,90 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
const common_1 = require("@nestjs/common");
const jwt_1 = require("@nestjs/jwt");
const users_service_1 = require("../users/users.service");
const bcrypt = __importStar(require("bcrypt"));
let AuthService = class AuthService {
usersService;
jwtService;
constructor(usersService, jwtService) {
this.usersService = usersService;
this.jwtService = jwtService;
}
async validateUser(username, password) {
const user = await this.usersService.findByUsername(username);
if (user && await bcrypt.compare(password, user.password)) {
return user;
}
return null;
}
async login(username, password) {
const user = await this.validateUser(username, password);
if (!user) {
throw new common_1.UnauthorizedException('Неверный логин или пароль');
}
const payload = { username: user.username, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
user,
};
}
async register(username, email, password) {
const user = await this.usersService.create(username, email, password);
const payload = { username: user.username, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
user,
};
}
};
exports.AuthService = AuthService;
exports.AuthService = AuthService = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [users_service_1.UsersService,
jwt_1.JwtService])
], AuthService);
//# sourceMappingURL=auth.service.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../src/modules/auth/auth.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAmE;AACnE,qCAAyC;AACzC,0DAAsD;AACtD,+CAAiC;AAI1B,IAAM,WAAW,GAAjB,MAAM,WAAW;IAEZ;IACA;IAFV,YACU,YAA0B,EAC1B,UAAsB;QADtB,iBAAY,GAAZ,YAAY,CAAc;QAC1B,eAAU,GAAV,UAAU,CAAY;IAC7B,CAAC;IAEJ,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,QAAgB;QACnD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,IAAI,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,QAAgB;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,8BAAqB,CAAC,2BAA2B,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAC1D,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IAAI;SACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,KAAa,EAAE,QAAgB;QAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAC1D,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;YAC3C,IAAI;SACL,CAAC;IACJ,CAAC;CACF,CAAA;AAnCY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAGa,4BAAY;QACd,gBAAU;GAHrB,WAAW,CAmCvB"}

View File

@ -0,0 +1 @@
export declare const CurrentUser: (...dataOrPipes: unknown[]) => ParameterDecorator;

View File

@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CurrentUser = void 0;
const common_1 = require("@nestjs/common");
const graphql_1 = require("@nestjs/graphql");
exports.CurrentUser = (0, common_1.createParamDecorator)((data, context) => {
const ctx = graphql_1.GqlExecutionContext.create(context);
return ctx.getContext().req.user;
});
//# sourceMappingURL=current-user.decorator.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"current-user.decorator.js","sourceRoot":"","sources":["../../../../src/modules/auth/decorators/current-user.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AACxE,6CAAsD;AAEzC,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,IAAa,EAAE,OAAyB,EAAE,EAAE;IAC3C,MAAM,GAAG,GAAG,6BAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACnC,CAAC,CACF,CAAC"}

View File

@ -0,0 +1,6 @@
import { ExecutionContext } from '@nestjs/common';
declare const GqlAuthGuard_base: import("@nestjs/passport").Type<import("@nestjs/passport").IAuthGuard>;
export declare class GqlAuthGuard extends GqlAuthGuard_base {
getRequest(context: ExecutionContext): any;
}
export {};

View File

@ -0,0 +1,23 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GqlAuthGuard = void 0;
const common_1 = require("@nestjs/common");
const passport_1 = require("@nestjs/passport");
const graphql_1 = require("@nestjs/graphql");
let GqlAuthGuard = class GqlAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
getRequest(context) {
const ctx = graphql_1.GqlExecutionContext.create(context);
return ctx.getContext().req;
}
};
exports.GqlAuthGuard = GqlAuthGuard;
exports.GqlAuthGuard = GqlAuthGuard = __decorate([
(0, common_1.Injectable)()
], GqlAuthGuard);
//# sourceMappingURL=gql-auth.guard.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"gql-auth.guard.js","sourceRoot":"","sources":["../../../../src/modules/auth/guards/gql-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA8D;AAC9D,+CAA6C;AAC7C,6CAAsD;AAG/C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,IAAA,oBAAS,EAAC,KAAK,CAAC;IAChD,UAAU,CAAC,OAAyB;QAClC,MAAM,GAAG,GAAG,6BAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,OAAO,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC;IAC9B,CAAC;CACF,CAAA;AALY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;GACA,YAAY,CAKxB"}

View File

@ -0,0 +1,11 @@
import { Strategy } from 'passport-jwt';
import { UsersService } from '../../users/users.service';
declare const JwtStrategy_base: new (...args: [opt: import("passport-jwt").StrategyOptionsWithRequest] | [opt: import("passport-jwt").StrategyOptionsWithoutRequest]) => Strategy & {
validate(...args: any[]): unknown;
};
export declare class JwtStrategy extends JwtStrategy_base {
private usersService;
constructor(usersService: UsersService);
validate(payload: any): Promise<import("../../users/entities/user.entity").User>;
}
export {};

View File

@ -0,0 +1,37 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JwtStrategy = void 0;
const passport_jwt_1 = require("passport-jwt");
const passport_1 = require("@nestjs/passport");
const common_1 = require("@nestjs/common");
const users_service_1 = require("../../users/users.service");
let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(passport_jwt_1.Strategy) {
usersService;
constructor(usersService) {
super({
jwtFromRequest: passport_jwt_1.ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET || 'secret',
});
this.usersService = usersService;
}
async validate(payload) {
const user = await this.usersService.findOne(payload.sub);
return user;
}
};
exports.JwtStrategy = JwtStrategy;
exports.JwtStrategy = JwtStrategy = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [users_service_1.UsersService])
], JwtStrategy);
//# sourceMappingURL=jwt.strategy.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../../../src/modules/auth/strategies/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+CAAoD;AACpD,+CAAoD;AACpD,2CAA4C;AAC5C,6DAAyD;AAGlD,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,IAAA,2BAAgB,EAAC,uBAAQ,CAAC;IACrC;IAApB,YAAoB,YAA0B;QAC5C,KAAK,CAAC;YACJ,cAAc,EAAE,yBAAU,CAAC,2BAA2B,EAAE;YACxD,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,QAAQ;SAChD,CAAC,CAAC;QALe,iBAAY,GAAZ,YAAY,CAAc;IAM9C,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAY;QACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAbY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAEuB,4BAAY;GADnC,WAAW,CAavB"}