diff --git a/.env.example b/.env.example
index 00b6110..c978a11 100644
--- a/.env.example
+++ b/.env.example
@@ -19,7 +19,7 @@ BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
-SESSION_DRIVER=file
+SESSION_DRIVER=database
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php
new file mode 100644
index 0000000..51132fd
--- /dev/null
+++ b/app/Actions/Fortify/CreateNewUser.php
@@ -0,0 +1,57 @@
+ ['required', 'string', 'max:255'],
+ 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
+ 'password' => $this->passwordRules(),
+ 'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
+ ])->validate();
+
+ return DB::transaction(function () use ($input) {
+ return tap(User::create([
+ 'name' => $input['name'],
+ 'email' => $input['email'],
+ 'password' => Hash::make($input['password']),
+ ]), function (User $user) {
+ $this->createTeam($user);
+ });
+ });
+ }
+
+ /**
+ * Create a personal team for the user.
+ *
+ * @param \App\Models\User $user
+ * @return void
+ */
+ protected function createTeam(User $user)
+ {
+ $user->ownedTeams()->save(Team::forceCreate([
+ 'user_id' => $user->id,
+ 'name' => explode(' ', $user->name, 2)[0]."'s Team",
+ 'personal_team' => true,
+ ]));
+ }
+}
diff --git a/app/Actions/Fortify/PasswordValidationRules.php b/app/Actions/Fortify/PasswordValidationRules.php
new file mode 100644
index 0000000..78ed8cf
--- /dev/null
+++ b/app/Actions/Fortify/PasswordValidationRules.php
@@ -0,0 +1,18 @@
+ $this->passwordRules(),
+ ])->validate();
+
+ $user->forceFill([
+ 'password' => Hash::make($input['password']),
+ ])->save();
+ }
+}
diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php
new file mode 100644
index 0000000..690f324
--- /dev/null
+++ b/app/Actions/Fortify/UpdateUserPassword.php
@@ -0,0 +1,35 @@
+ ['required', 'string'],
+ 'password' => $this->passwordRules(),
+ ])->after(function ($validator) use ($user, $input) {
+ if (! isset($input['current_password']) || ! Hash::check($input['current_password'], $user->password)) {
+ $validator->errors()->add('current_password', __('The provided password does not match your current password.'));
+ }
+ })->validateWithBag('updatePassword');
+
+ $user->forceFill([
+ 'password' => Hash::make($input['password']),
+ ])->save();
+ }
+}
diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php
new file mode 100644
index 0000000..c757632
--- /dev/null
+++ b/app/Actions/Fortify/UpdateUserProfileInformation.php
@@ -0,0 +1,59 @@
+ ['required', 'string', 'max:255'],
+ 'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
+ 'photo' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'],
+ ])->validateWithBag('updateProfileInformation');
+
+ if (isset($input['photo'])) {
+ $user->updateProfilePhoto($input['photo']);
+ }
+
+ if ($input['email'] !== $user->email &&
+ $user instanceof MustVerifyEmail) {
+ $this->updateVerifiedUser($user, $input);
+ } else {
+ $user->forceFill([
+ 'name' => $input['name'],
+ 'email' => $input['email'],
+ ])->save();
+ }
+ }
+
+ /**
+ * Update the given verified user's profile information.
+ *
+ * @param mixed $user
+ * @param array $input
+ * @return void
+ */
+ protected function updateVerifiedUser($user, array $input)
+ {
+ $user->forceFill([
+ 'name' => $input['name'],
+ 'email' => $input['email'],
+ 'email_verified_at' => null,
+ ])->save();
+
+ $user->sendEmailVerificationNotification();
+ }
+}
diff --git a/app/Actions/Jetstream/AddTeamMember.php b/app/Actions/Jetstream/AddTeamMember.php
new file mode 100644
index 0000000..dddd5b5
--- /dev/null
+++ b/app/Actions/Jetstream/AddTeamMember.php
@@ -0,0 +1,93 @@
+authorize('addTeamMember', $team);
+
+ $this->validate($team, $email, $role);
+
+ $newTeamMember = Jetstream::findUserByEmailOrFail($email);
+
+ AddingTeamMember::dispatch($team, $newTeamMember);
+
+ $team->users()->attach(
+ $newTeamMember, ['role' => $role]
+ );
+
+ TeamMemberAdded::dispatch($team, $newTeamMember);
+ }
+
+ /**
+ * Validate the add member operation.
+ *
+ * @param mixed $team
+ * @param string $email
+ * @param string|null $role
+ * @return void
+ */
+ protected function validate($team, string $email, ?string $role)
+ {
+ Validator::make([
+ 'email' => $email,
+ 'role' => $role,
+ ], $this->rules(), [
+ 'email.exists' => __('We were unable to find a registered user with this email address.'),
+ ])->after(
+ $this->ensureUserIsNotAlreadyOnTeam($team, $email)
+ )->validateWithBag('addTeamMember');
+ }
+
+ /**
+ * Get the validation rules for adding a team member.
+ *
+ * @return array
+ */
+ protected function rules()
+ {
+ return array_filter([
+ 'email' => ['required', 'email', 'exists:users'],
+ 'role' => Jetstream::hasRoles()
+ ? ['required', 'string', new Role]
+ : null,
+ ]);
+ }
+
+ /**
+ * Ensure that the user is not already on the team.
+ *
+ * @param mixed $team
+ * @param string $email
+ * @return \Closure
+ */
+ protected function ensureUserIsNotAlreadyOnTeam($team, string $email)
+ {
+ return function ($validator) use ($team, $email) {
+ $validator->errors()->addIf(
+ $team->hasUserWithEmail($email),
+ 'email',
+ __('This user already belongs to the team.')
+ );
+ };
+ }
+}
diff --git a/app/Actions/Jetstream/CreateTeam.php b/app/Actions/Jetstream/CreateTeam.php
new file mode 100644
index 0000000..b47710e
--- /dev/null
+++ b/app/Actions/Jetstream/CreateTeam.php
@@ -0,0 +1,37 @@
+authorize('create', Jetstream::newTeamModel());
+
+ Validator::make($input, [
+ 'name' => ['required', 'string', 'max:255'],
+ ])->validateWithBag('createTeam');
+
+ AddingTeam::dispatch($user);
+
+ $user->switchTeam($team = $user->ownedTeams()->create([
+ 'name' => $input['name'],
+ 'personal_team' => false,
+ ]));
+
+ return $team;
+ }
+}
diff --git a/app/Actions/Jetstream/DeleteTeam.php b/app/Actions/Jetstream/DeleteTeam.php
new file mode 100644
index 0000000..c300e10
--- /dev/null
+++ b/app/Actions/Jetstream/DeleteTeam.php
@@ -0,0 +1,19 @@
+purge();
+ }
+}
diff --git a/app/Actions/Jetstream/DeleteUser.php b/app/Actions/Jetstream/DeleteUser.php
new file mode 100644
index 0000000..65a127f
--- /dev/null
+++ b/app/Actions/Jetstream/DeleteUser.php
@@ -0,0 +1,59 @@
+deletesTeams = $deletesTeams;
+ }
+
+ /**
+ * Delete the given user.
+ *
+ * @param mixed $user
+ * @return void
+ */
+ public function delete($user)
+ {
+ DB::transaction(function () use ($user) {
+ $this->deleteTeams($user);
+ $user->deleteProfilePhoto();
+ $user->tokens->each->delete();
+ $user->delete();
+ });
+ }
+
+ /**
+ * Delete the teams and team associations attached to the user.
+ *
+ * @param mixed $user
+ * @return void
+ */
+ protected function deleteTeams($user)
+ {
+ $user->teams()->detach();
+
+ $user->ownedTeams->each(function ($team) {
+ $this->deletesTeams->delete($team);
+ });
+ }
+}
diff --git a/app/Actions/Jetstream/InviteTeamMember.php b/app/Actions/Jetstream/InviteTeamMember.php
new file mode 100644
index 0000000..d49d85f
--- /dev/null
+++ b/app/Actions/Jetstream/InviteTeamMember.php
@@ -0,0 +1,97 @@
+authorize('addTeamMember', $team);
+
+ $this->validate($team, $email, $role);
+
+ InvitingTeamMember::dispatch($team, $email, $role);
+
+ $invitation = $team->teamInvitations()->create([
+ 'email' => $email,
+ 'role' => $role,
+ ]);
+
+ Mail::to($email)->send(new TeamInvitation($invitation));
+ }
+
+ /**
+ * Validate the invite member operation.
+ *
+ * @param mixed $team
+ * @param string $email
+ * @param string|null $role
+ * @return void
+ */
+ protected function validate($team, string $email, ?string $role)
+ {
+ Validator::make([
+ 'email' => $email,
+ 'role' => $role,
+ ], $this->rules($team), [
+ 'email.unique' => __('This user has already been invited to the team.'),
+ ])->after(
+ $this->ensureUserIsNotAlreadyOnTeam($team, $email)
+ )->validateWithBag('addTeamMember');
+ }
+
+ /**
+ * Get the validation rules for inviting a team member.
+ *
+ * @param mixed $team
+ * @return array
+ */
+ protected function rules($team)
+ {
+ return array_filter([
+ 'email' => ['required', 'email', Rule::unique('team_invitations')->where(function ($query) use ($team) {
+ $query->where('team_id', $team->id);
+ })],
+ 'role' => Jetstream::hasRoles()
+ ? ['required', 'string', new Role]
+ : null,
+ ]);
+ }
+
+ /**
+ * Ensure that the user is not already on the team.
+ *
+ * @param mixed $team
+ * @param string $email
+ * @return \Closure
+ */
+ protected function ensureUserIsNotAlreadyOnTeam($team, string $email)
+ {
+ return function ($validator) use ($team, $email) {
+ $validator->errors()->addIf(
+ $team->hasUserWithEmail($email),
+ 'email',
+ __('This user already belongs to the team.')
+ );
+ };
+ }
+}
diff --git a/app/Actions/Jetstream/RemoveTeamMember.php b/app/Actions/Jetstream/RemoveTeamMember.php
new file mode 100644
index 0000000..cd28f83
--- /dev/null
+++ b/app/Actions/Jetstream/RemoveTeamMember.php
@@ -0,0 +1,63 @@
+authorize($user, $team, $teamMember);
+
+ $this->ensureUserDoesNotOwnTeam($teamMember, $team);
+
+ $team->removeUser($teamMember);
+
+ TeamMemberRemoved::dispatch($team, $teamMember);
+ }
+
+ /**
+ * Authorize that the user can remove the team member.
+ *
+ * @param mixed $user
+ * @param mixed $team
+ * @param mixed $teamMember
+ * @return void
+ */
+ protected function authorize($user, $team, $teamMember)
+ {
+ if (! Gate::forUser($user)->check('removeTeamMember', $team) &&
+ $user->id !== $teamMember->id) {
+ throw new AuthorizationException;
+ }
+ }
+
+ /**
+ * Ensure that the currently authenticated user does not own the team.
+ *
+ * @param mixed $teamMember
+ * @param mixed $team
+ * @return void
+ */
+ protected function ensureUserDoesNotOwnTeam($teamMember, $team)
+ {
+ if ($teamMember->id === $team->owner->id) {
+ throw ValidationException::withMessages([
+ 'team' => [__('You may not leave a team that you created.')],
+ ])->errorBag('removeTeamMember');
+ }
+ }
+}
diff --git a/app/Actions/Jetstream/UpdateTeamName.php b/app/Actions/Jetstream/UpdateTeamName.php
new file mode 100644
index 0000000..2006c94
--- /dev/null
+++ b/app/Actions/Jetstream/UpdateTeamName.php
@@ -0,0 +1,31 @@
+authorize('update', $team);
+
+ Validator::make($input, [
+ 'name' => ['required', 'string', 'max:255'],
+ ])->validateWithBag('updateTeamName');
+
+ $team->forceFill([
+ 'name' => $input['name'],
+ ])->save();
+ }
+}
diff --git a/app/Http/Controllers/Api/ProyectoController.php b/app/Http/Controllers/Api/ProyectoController.php
new file mode 100644
index 0000000..ccb9229
--- /dev/null
+++ b/app/Http/Controllers/Api/ProyectoController.php
@@ -0,0 +1,70 @@
+get();
+
+ //var_dump($proyectos);
+
+ return ProyectoResource::collection($proyectos);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function store(Request $request)
+ {
+ //
+ }
+
+ /**
+ * Display the specified resource.
+ *
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function show(Proyecto $proyecto)
+ {
+ //
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function update(Request $request, Proyecto $proyecto)
+ {
+ //
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy(Proyecto $proyecto)
+ {
+ //
+ }
+}
diff --git a/app/Http/Controllers/AsignacionController.php b/app/Http/Controllers/AsignacionController.php
new file mode 100644
index 0000000..18f663a
--- /dev/null
+++ b/app/Http/Controllers/AsignacionController.php
@@ -0,0 +1,172 @@
+orderBy('created_at','ASC')->get();
+ }
+ else{
+ $asignaciones=Asignacion::orderBy('created_at','ASC')->get();
+ }
+
+ $data = [
+ 'cooperantes' => $cooperantes,
+ 'asignaciones' => $asignaciones
+ ];
+ //var_dump($asignaciones);
+
+ return View('asignaciones.index', $data);
+ }
+
+ public function obtenerReporte($cooperante=null){
+
+ //dd($cooperante);
+
+ if(isset($cooperante)){
+ $asignaciones=Asignacion::where("cooperante_id","=", $cooperante)->orderBy('created_at','ASC')->get();
+ }
+ else{
+ $asignaciones=Asignacion::orderBy('created_at','DESC')->get();
+ }
+
+ //dd($asignaciones);
+
+ $filtro="";
+ $total=0;
+
+ foreach($asignaciones as $asignacion){
+ $filtro.="
+ ".$asignacion->id."
+ ".$asignacion->cooperante->nombre."
+ ".$asignacion->proyecto->nombre."
+ ".$asignacion->fechaAsignacion->format('d/m/Y')."
+ ".$asignacion->monto."
+ ";
+ $total+=$asignacion->monto;
+ }
+
+ $filtro.="
+
+
+
+ Total
+ ".$total."
+ ";
+
+ return $filtro;
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function create()
+ {
+ $proyectos=Proyecto::all();
+
+ $cooperantes=Cooperante::all();
+
+ $data = [
+ 'proyectos' => $proyectos,
+ 'cooperantes' => $cooperantes,
+ 'asignacion' => new Asignacion
+ ];
+
+ //var_dump($data);
+
+ return View('asignaciones.create', $data);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function store(SaveAsignacionRequest $request)
+ {
+ //var_dump($request);
+
+ Asignacion::create($request->validated());
+
+ return redirect()->route('asignaciones.reporte')->with('status', 'La asignacion fue creada con éxito.');
+ }
+
+ /**
+ * Display the specified resource.
+ *
+ * @param \App\Models\Asignacion $asignacion
+ * @return \Illuminate\Http\Response
+ */
+ public function show(Asignacion $asignacion)
+ {
+ //
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param \App\Models\Asignacion $asignacion
+ * @return \Illuminate\Http\Response
+ */
+ public function edit(Asignacion $asignacion)
+ {
+ $proyectos=Proyecto::all();
+
+ $cooperantes=Cooperante::all();
+
+ $data = [
+ 'proyectos' => $proyectos,
+ 'cooperantes' => $cooperantes,
+ 'asignacion' => $asignacion
+ ];
+
+ //dd($asignacion);
+
+ return View('asignaciones.edit', $data);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \App\Models\Asignacion $asignacion
+ * @return \Illuminate\Http\Response
+ */
+ public function update(SaveAsignacionRequest $request, Asignacion $asignacion)
+ {
+ $asignacion->update($request->validated());
+
+ return redirect()->route('asignaciones.reporte')->with('status', 'La asignación fue actualizada con éxito.');
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param \App\Models\Asignacion $asignacion
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy(Asignacion $asignacion)
+ {
+ //
+ }
+}
diff --git a/app/Http/Controllers/CooperanteController.php b/app/Http/Controllers/CooperanteController.php
new file mode 100644
index 0000000..83117f9
--- /dev/null
+++ b/app/Http/Controllers/CooperanteController.php
@@ -0,0 +1,104 @@
+get();
+
+ //var_dump($cooperantes);
+
+ return View('cooperantes.index', [
+ 'cooperantes' => Cooperante::latest('updated_at')->paginate()
+ ]);
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function create()
+ {
+ return View('cooperantes.create',[
+ 'cooperante' => new Cooperante
+ ]);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function store(SaveCooperanteRequest $request)
+ {
+ Cooperante::create($request->validated());
+
+ return redirect()->route('cooperantes.index')->with('status', 'El cooperante fue creado con éxito.');
+ }
+
+ /**
+ * Display the specified resource.
+ *
+ * @param \App\Models\Cooperante $cooperante
+ * @return \Illuminate\Http\Response
+ */
+ public function show(Cooperante $cooperante)
+ {
+ return View('cooperantes.show',[
+ 'cooperante' => $cooperante
+ ]);
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param \App\Models\Cooperante $cooperante
+ * @return \Illuminate\Http\Response
+ */
+ public function edit(Cooperante $cooperante)
+ {
+ return View('cooperantes.edit',[
+ 'cooperante' => $cooperante
+ ]);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \App\Models\Cooperante $cooperante
+ * @return \Illuminate\Http\Response
+ */
+ public function update(SaveCooperanteRequest $request, Cooperante $cooperante)
+ {
+ $cooperante->update($request->validated());
+
+ return redirect()->route('cooperantes.index',$cooperante)->with('status', 'El cooperante fue actualizado con éxito.');
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param \App\Models\Cooperante $cooperante
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy(Cooperante $cooperante)
+ {
+ $cooperante->delete();
+
+ return redirect()->route('cooperantes.index')->with('status', 'El cooperante fue eliminado con éxito.');
+ }
+}
diff --git a/app/Http/Controllers/ProyectoController.php b/app/Http/Controllers/ProyectoController.php
new file mode 100644
index 0000000..f936f0b
--- /dev/null
+++ b/app/Http/Controllers/ProyectoController.php
@@ -0,0 +1,112 @@
+middleware('auth',['except' => ['index','show']]);
+ }
+
+ /**
+ * Display a listing of the resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function index()
+ {
+ $proyectos=Proyecto::latest('updated_at')->get();
+
+ //var_dump($proyectos);
+
+ return View('proyectos.index', [
+ 'proyectos' => Proyecto::latest('updated_at')->paginate()
+ ]);
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function create()
+ {
+ return View('proyectos.create',[
+ 'proyecto' => new Proyecto
+ ]);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function store(SaveProyectoRequest $request)
+ {
+ Proyecto::create($request->validated());
+
+ session()->flash('status', 'El proyecto fue creado con éxito.');
+
+ return redirect()->route('proyectos.index');
+
+ //return redirect()->route('proyectos.index')->with('status', 'El proyecto fue creado con éxito.');
+ }
+
+ /**
+ * Display the specified resource.
+ *
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function show(Proyecto $proyecto)
+ {
+ return View('proyectos.show',[
+ 'proyecto' => $proyecto
+ ]);
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function edit(Proyecto $proyecto)
+ {
+ return View('proyectos.edit',[
+ 'proyecto' => $proyecto
+ ]);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function update(SaveProyectoRequest $request, Proyecto $proyecto)
+ {
+ $proyecto->update($request->validated());
+
+ return redirect()->route('proyectos.index',$proyecto)->with('status', 'El proyecto fue actualizado con éxito.');
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param \App\Models\Proyecto $proyecto
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy(Proyecto $proyecto)
+ {
+ $proyecto->delete();
+
+ return redirect()->route('proyectos.index')->with('status', 'El proyecto fue eliminado con éxito.');
+ }
+}
diff --git a/app/Http/Requests/SaveAsignacionRequest.php b/app/Http/Requests/SaveAsignacionRequest.php
new file mode 100644
index 0000000..8ad4d27
--- /dev/null
+++ b/app/Http/Requests/SaveAsignacionRequest.php
@@ -0,0 +1,42 @@
+
+ */
+ public function rules()
+ {
+ return [
+ 'cooperante_id' => ['required'],
+ 'proyecto_id' => ['required'],
+ 'fechaAsignacion' => ['required'],
+ 'monto' => ['required','gt:0']
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'cooperante_id.required' => 'Favor seleccionar el cooperante',
+ 'proyecto_id.required' => 'Favor seleccionar el proyecto',
+ 'fechaAsignacion.required' => 'Favor digitar la fecha de asignación',
+ 'fechaAsignacion.monto' => 'Favor digitar el monto'
+ ];
+ }
+}
diff --git a/app/Http/Requests/SaveCooperanteRequest.php b/app/Http/Requests/SaveCooperanteRequest.php
new file mode 100644
index 0000000..a9e87a1
--- /dev/null
+++ b/app/Http/Requests/SaveCooperanteRequest.php
@@ -0,0 +1,40 @@
+
+ */
+ public function rules()
+ {
+ return [
+ 'nombre' => ['required'],
+ 'email' => ['required'],
+ 'direccion' => ['required']
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'nombre.required' => 'Favor digitar el nombre',
+ 'email.required' => 'Favor digitar el email',
+ 'direccion.required' => 'Favor digitar la direccion'
+ ];
+ }
+}
diff --git a/app/Http/Requests/SaveProyectoRequest.php b/app/Http/Requests/SaveProyectoRequest.php
new file mode 100644
index 0000000..c591589
--- /dev/null
+++ b/app/Http/Requests/SaveProyectoRequest.php
@@ -0,0 +1,38 @@
+
+ */
+ public function rules()
+ {
+ return [
+ 'nombre' => ['required'],
+ 'descripcion' => ['required'],
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'nombre.required' => 'Favor digitar el nombre',
+ 'descripcion.required' => 'Favor digitar el email',
+ ];
+ }
+}
diff --git a/app/Http/Resources/ProyectoResource.php b/app/Http/Resources/ProyectoResource.php
new file mode 100644
index 0000000..da93b2c
--- /dev/null
+++ b/app/Http/Resources/ProyectoResource.php
@@ -0,0 +1,19 @@
+ 'integer',
+ 'proyecto_id' => 'integer',
+ 'fechaAsignacion' => 'datetime',
+ ];
+
+ public function cooperante()
+ {
+ return $this->belongsTo(Cooperante::class);
+ }
+
+ public function proyecto()
+ {
+ return $this->belongsTo(Proyecto::class);
+ }
+}
diff --git a/app/Models/Cooperante.php b/app/Models/Cooperante.php
new file mode 100644
index 0000000..26d55c2
--- /dev/null
+++ b/app/Models/Cooperante.php
@@ -0,0 +1,18 @@
+hasMany(Cooperante::class);
+ }
+}
diff --git a/app/Models/Membership.php b/app/Models/Membership.php
new file mode 100644
index 0000000..f4ca843
--- /dev/null
+++ b/app/Models/Membership.php
@@ -0,0 +1,15 @@
+hasMany(Cooperante::class);
+ }
+}
diff --git a/app/Models/Team.php b/app/Models/Team.php
new file mode 100644
index 0000000..e63d9a5
--- /dev/null
+++ b/app/Models/Team.php
@@ -0,0 +1,44 @@
+ 'boolean',
+ ];
+
+ /**
+ * The attributes that are mass assignable.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'name',
+ 'personal_team',
+ ];
+
+ /**
+ * The event map for the model.
+ *
+ * @var array
+ */
+ protected $dispatchesEvents = [
+ 'created' => TeamCreated::class,
+ 'updated' => TeamUpdated::class,
+ 'deleted' => TeamDeleted::class,
+ ];
+}
diff --git a/app/Models/TeamInvitation.php b/app/Models/TeamInvitation.php
new file mode 100644
index 0000000..265e73b
--- /dev/null
+++ b/app/Models/TeamInvitation.php
@@ -0,0 +1,29 @@
+belongsTo(Jetstream::teamModel());
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 23b4063..0690041 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -2,43 +2,60 @@
namespace App\Models;
-// use Illuminate\Contracts\Auth\MustVerifyEmail;
+use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
+use Laravel\Fortify\TwoFactorAuthenticatable;
+use Laravel\Jetstream\HasProfilePhoto;
+use Laravel\Jetstream\HasTeams;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
- use HasApiTokens, HasFactory, Notifiable;
+ use HasApiTokens;
+ use HasFactory;
+ use HasProfilePhoto;
+ use HasTeams;
+ use Notifiable;
+ use TwoFactorAuthenticatable;
/**
* The attributes that are mass assignable.
*
- * @var array
+ * @var string[]
*/
protected $fillable = [
- 'name',
- 'email',
- 'password',
+ 'name', 'email', 'password',
];
/**
* The attributes that should be hidden for serialization.
*
- * @var array
+ * @var array
*/
protected $hidden = [
'password',
'remember_token',
+ 'two_factor_recovery_codes',
+ 'two_factor_secret',
];
/**
* The attributes that should be cast.
*
- * @var array
+ * @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
+
+ /**
+ * The accessors to append to the model's array form.
+ *
+ * @var array
+ */
+ protected $appends = [
+ 'profile_photo_url',
+ ];
}
diff --git a/app/Policies/TeamPolicy.php b/app/Policies/TeamPolicy.php
new file mode 100644
index 0000000..277163c
--- /dev/null
+++ b/app/Policies/TeamPolicy.php
@@ -0,0 +1,106 @@
+belongsToTeam($team);
+ }
+
+ /**
+ * Determine whether the user can create models.
+ *
+ * @param \App\Models\User $user
+ * @return mixed
+ */
+ public function create(User $user)
+ {
+ return true;
+ }
+
+ /**
+ * Determine whether the user can update the model.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Team $team
+ * @return mixed
+ */
+ public function update(User $user, Team $team)
+ {
+ return $user->ownsTeam($team);
+ }
+
+ /**
+ * Determine whether the user can add team members.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Team $team
+ * @return mixed
+ */
+ public function addTeamMember(User $user, Team $team)
+ {
+ return $user->ownsTeam($team);
+ }
+
+ /**
+ * Determine whether the user can update team member permissions.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Team $team
+ * @return mixed
+ */
+ public function updateTeamMember(User $user, Team $team)
+ {
+ return $user->ownsTeam($team);
+ }
+
+ /**
+ * Determine whether the user can remove team members.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Team $team
+ * @return mixed
+ */
+ public function removeTeamMember(User $user, Team $team)
+ {
+ return $user->ownsTeam($team);
+ }
+
+ /**
+ * Determine whether the user can delete the model.
+ *
+ * @param \App\Models\User $user
+ * @param \App\Models\Team $team
+ * @return mixed
+ */
+ public function delete(User $user, Team $team)
+ {
+ return $user->ownsTeam($team);
+ }
+}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index ee8ca5b..d359c79 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -3,6 +3,7 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
+use Illuminate\Support\Facades\Blade;
class AppServiceProvider extends ServiceProvider
{
@@ -23,6 +24,8 @@ public function register()
*/
public function boot()
{
- //
+ Blade::directive('money', function ($amount) {
+ return "";
+ });
}
}
diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php
index 33b83f5..39a6724 100644
--- a/app/Providers/AuthServiceProvider.php
+++ b/app/Providers/AuthServiceProvider.php
@@ -2,18 +2,19 @@
namespace App\Providers;
-// use Illuminate\Support\Facades\Gate;
+use App\Models\Team;
+use App\Policies\TeamPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
- * The model to policy mappings for the application.
+ * The policy mappings for the application.
*
- * @var array
+ * @var array
*/
protected $policies = [
- // 'App\Models\Model' => 'App\Policies\ModelPolicy',
+ Team::class => TeamPolicy::class,
];
/**
diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php
new file mode 100644
index 0000000..9f2f3c1
--- /dev/null
+++ b/app/Providers/FortifyServiceProvider.php
@@ -0,0 +1,49 @@
+email;
+
+ return Limit::perMinute(5)->by($email.$request->ip());
+ });
+
+ RateLimiter::for('two-factor', function (Request $request) {
+ return Limit::perMinute(5)->by($request->session()->get('login.id'));
+ });
+ }
+}
diff --git a/app/Providers/JetstreamServiceProvider.php b/app/Providers/JetstreamServiceProvider.php
new file mode 100644
index 0000000..abad0dd
--- /dev/null
+++ b/app/Providers/JetstreamServiceProvider.php
@@ -0,0 +1,67 @@
+configurePermissions();
+
+ Jetstream::createTeamsUsing(CreateTeam::class);
+ Jetstream::updateTeamNamesUsing(UpdateTeamName::class);
+ Jetstream::addTeamMembersUsing(AddTeamMember::class);
+ Jetstream::inviteTeamMembersUsing(InviteTeamMember::class);
+ Jetstream::removeTeamMembersUsing(RemoveTeamMember::class);
+ Jetstream::deleteTeamsUsing(DeleteTeam::class);
+ Jetstream::deleteUsersUsing(DeleteUser::class);
+ }
+
+ /**
+ * Configure the roles and permissions that are available within the application.
+ *
+ * @return void
+ */
+ protected function configurePermissions()
+ {
+ Jetstream::defaultApiTokenPermissions(['read']);
+
+ Jetstream::role('admin', 'Administrator', [
+ 'create',
+ 'read',
+ 'update',
+ 'delete',
+ ])->description('Administrator users can perform any action.');
+
+ Jetstream::role('editor', 'Editor', [
+ 'read',
+ 'create',
+ 'update',
+ ])->description('Editor users have the ability to read, create, and update.');
+ }
+}
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
index ea87f2e..52dabc1 100644
--- a/app/Providers/RouteServiceProvider.php
+++ b/app/Providers/RouteServiceProvider.php
@@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
*
* @var string
*/
- public const HOME = '/home';
+ public const HOME = '/dashboard';
/**
* Define your route model bindings, pattern filters, and other route configuration.
diff --git a/app/View/Components/AppLayout.php b/app/View/Components/AppLayout.php
new file mode 100644
index 0000000..b45d342
--- /dev/null
+++ b/app/View/Components/AppLayout.php
@@ -0,0 +1,18 @@
+=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8|^5.5|^6.5|^9.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Jaybizzle\\CrawlerDetect\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Beech",
+ "email": "m@rkbee.ch",
+ "role": "Developer"
+ }
+ ],
+ "description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent",
+ "homepage": "https://github.com/JayBizzle/Crawler-Detect/",
+ "keywords": [
+ "crawler",
+ "crawler detect",
+ "crawler detector",
+ "crawlerdetect",
+ "php crawler detect"
+ ],
+ "support": {
+ "issues": "https://github.com/JayBizzle/Crawler-Detect/issues",
+ "source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.111"
+ },
+ "time": "2022-03-15T22:19:01+00:00"
+ },
+ {
+ "name": "jenssegers/agent",
+ "version": "v2.6.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jenssegers/agent.git",
+ "reference": "daa11c43729510b3700bc34d414664966b03bffe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jenssegers/agent/zipball/daa11c43729510b3700bc34d414664966b03bffe",
+ "reference": "daa11c43729510b3700bc34d414664966b03bffe",
+ "shasum": ""
+ },
+ "require": {
+ "jaybizzle/crawler-detect": "^1.2",
+ "mobiledetect/mobiledetectlib": "^2.7.6",
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5.0|^6.0|^7.0"
+ },
+ "suggest": {
+ "illuminate/support": "Required for laravel service providers"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Jenssegers\\Agent\\AgentServiceProvider"
+ ],
+ "aliases": {
+ "Agent": "Jenssegers\\Agent\\Facades\\Agent"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Jenssegers\\Agent\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jens Segers",
+ "homepage": "https://jenssegers.com"
+ }
+ ],
+ "description": "Desktop/mobile user agent parser with support for Laravel, based on Mobiledetect",
+ "homepage": "https://github.com/jenssegers/agent",
+ "keywords": [
+ "Agent",
+ "browser",
+ "desktop",
+ "laravel",
+ "mobile",
+ "platform",
+ "user agent",
+ "useragent"
+ ],
+ "support": {
+ "issues": "https://github.com/jenssegers/agent/issues",
+ "source": "https://github.com/jenssegers/agent/tree/v2.6.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/jenssegers",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/jenssegers/agent",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-06-13T08:05:20+00:00"
+ },
+ {
+ "name": "laravel/fortify",
+ "version": "v1.13.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/fortify.git",
+ "reference": "9a68cf2deb37d1796b6e2fd97d3c61f086868914"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/fortify/zipball/9a68cf2deb37d1796b6e2fd97d3c61f086868914",
+ "reference": "9a68cf2deb37d1796b6e2fd97d3c61f086868914",
+ "shasum": ""
+ },
+ "require": {
+ "bacon/bacon-qr-code": "^2.0",
+ "ext-json": "*",
+ "illuminate/support": "^8.82|^9.0",
+ "php": "^7.3|^8.0",
+ "pragmarx/google2fa": "^7.0|^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "orchestra/testbench": "^6.0|^7.0",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Fortify\\FortifyServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Fortify\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Backend controllers and scaffolding for Laravel authentication.",
+ "keywords": [
+ "auth",
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/fortify/issues",
+ "source": "https://github.com/laravel/fortify"
+ },
+ "time": "2022-09-30T13:20:14+00:00"
+ },
{
"name": "laravel/framework",
"version": "v9.26.1",
@@ -1077,6 +1376,76 @@
},
"time": "2022-08-23T19:00:07+00:00"
},
+ {
+ "name": "laravel/jetstream",
+ "version": "v2.12.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/jetstream.git",
+ "reference": "0abb8071c543823855f1618a448dbd900bafda3a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/jetstream/zipball/0abb8071c543823855f1618a448dbd900bafda3a",
+ "reference": "0abb8071c543823855f1618a448dbd900bafda3a",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "illuminate/console": "^9.21",
+ "illuminate/support": "^9.21",
+ "jenssegers/agent": "^2.6",
+ "laravel/fortify": "^1.13.3",
+ "php": "^8.0.2"
+ },
+ "conflict": {
+ "laravel/framework": "<9.19.0"
+ },
+ "require-dev": {
+ "inertiajs/inertia-laravel": "^0.6.3",
+ "laravel/sanctum": "^3.0",
+ "mockery/mockery": "^1.0",
+ "orchestra/testbench": "^7.0",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Jetstream\\JetstreamServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Jetstream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Tailwind scaffolding for the Laravel framework.",
+ "keywords": [
+ "auth",
+ "laravel",
+ "tailwind"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/jetstream/issues",
+ "source": "https://github.com/laravel/jetstream"
+ },
+ "time": "2022-09-26T13:49:44+00:00"
+ },
{
"name": "laravel/sanctum",
"version": "v3.0.1",
@@ -1603,6 +1972,135 @@
],
"time": "2022-04-17T13:12:02+00:00"
},
+ {
+ "name": "livewire/livewire",
+ "version": "v2.10.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/livewire/livewire.git",
+ "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/livewire/livewire/zipball/fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
+ "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/database": "^7.0|^8.0|^9.0",
+ "illuminate/support": "^7.0|^8.0|^9.0",
+ "illuminate/validation": "^7.0|^8.0|^9.0",
+ "league/mime-type-detection": "^1.9",
+ "php": "^7.2.5|^8.0",
+ "symfony/http-kernel": "^5.0|^6.0"
+ },
+ "require-dev": {
+ "calebporzio/sushi": "^2.1",
+ "laravel/framework": "^7.0|^8.0|^9.0",
+ "mockery/mockery": "^1.3.1",
+ "orchestra/testbench": "^5.0|^6.0|^7.0",
+ "orchestra/testbench-dusk": "^5.2|^6.0|^7.0",
+ "phpunit/phpunit": "^8.4|^9.0",
+ "psy/psysh": "@stable"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Livewire\\LivewireServiceProvider"
+ ],
+ "aliases": {
+ "Livewire": "Livewire\\Livewire"
+ }
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
+ "psr-4": {
+ "Livewire\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Caleb Porzio",
+ "email": "calebporzio@gmail.com"
+ }
+ ],
+ "description": "A front-end framework for Laravel.",
+ "support": {
+ "issues": "https://github.com/livewire/livewire/issues",
+ "source": "https://github.com/livewire/livewire/tree/v2.10.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/livewire",
+ "type": "github"
+ }
+ ],
+ "time": "2022-08-08T13:52:53+00:00"
+ },
+ {
+ "name": "mobiledetect/mobiledetectlib",
+ "version": "2.8.39",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/serbanghita/Mobile-Detect.git",
+ "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/0fd6753003fc870f6e229bae869cc1337c99bc45",
+ "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8.35||~5.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Detection": "namespaced/"
+ },
+ "classmap": [
+ "Mobile_Detect.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Serban Ghita",
+ "email": "serbanghita@gmail.com",
+ "homepage": "http://mobiledetect.net",
+ "role": "Developer"
+ }
+ ],
+ "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
+ "homepage": "https://github.com/serbanghita/Mobile-Detect",
+ "keywords": [
+ "detect mobile devices",
+ "mobile",
+ "mobile detect",
+ "mobile detector",
+ "php mobile detect"
+ ],
+ "support": {
+ "issues": "https://github.com/serbanghita/Mobile-Detect/issues",
+ "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.39"
+ },
+ "time": "2022-02-17T19:24:25+00:00"
+ },
{
"name": "monolog/monolog",
"version": "2.8.0",
@@ -2096,6 +2594,73 @@
],
"time": "2022-08-01T11:03:24+00:00"
},
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v2.6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "58c3f47f650c94ec05a151692652a868995d2938"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
+ "reference": "58c3f47f650c94ec05a151692652a868995d2938",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2022-06-14T06:56:20+00:00"
+ },
{
"name": "phpoption/phpoption",
"version": "1.9.0",
@@ -2171,6 +2736,58 @@
],
"time": "2022-07-30T15:51:26+00:00"
},
+ {
+ "name": "pragmarx/google2fa",
+ "version": "v8.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/antonioribeiro/google2fa.git",
+ "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/80c3d801b31fe165f8fe99ea085e0a37834e1be3",
+ "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/constant_time_encoding": "^1.0|^2.0",
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12.18",
+ "phpunit/phpunit": "^7.5.15|^8.5|^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PragmaRX\\Google2FA\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Antonio Carlos Ribeiro",
+ "email": "acr@antoniocarlosribeiro.com",
+ "role": "Creator & Designer"
+ }
+ ],
+ "description": "A One Time Password Authentication package, compatible with Google Authenticator.",
+ "keywords": [
+ "2fa",
+ "Authentication",
+ "Two Factor Authentication",
+ "google2fa"
+ ],
+ "support": {
+ "issues": "https://github.com/antonioribeiro/google2fa/issues",
+ "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.1"
+ },
+ "time": "2022-06-13T21:57:56+00:00"
+ },
{
"name": "psr/container",
"version": "2.0.2",
diff --git a/config/app.php b/config/app.php
index ef76a7e..f66af84 100644
--- a/config/app.php
+++ b/config/app.php
@@ -194,6 +194,8 @@
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
+ App\Providers\FortifyServiceProvider::class,
+ App\Providers\JetstreamServiceProvider::class,
],
diff --git a/config/fortify.php b/config/fortify.php
new file mode 100644
index 0000000..510a539
--- /dev/null
+++ b/config/fortify.php
@@ -0,0 +1,147 @@
+ 'web',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Fortify Password Broker
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify which password broker Fortify can use when a user
+ | is resetting their password. This configured value should match one
+ | of your password brokers setup in your "auth" configuration file.
+ |
+ */
+
+ 'passwords' => 'users',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Username / Email
+ |--------------------------------------------------------------------------
+ |
+ | This value defines which model attribute should be considered as your
+ | application's "username" field. Typically, this might be the email
+ | address of the users but you are free to change this value here.
+ |
+ | Out of the box, Fortify expects forgot password and reset password
+ | requests to have a field named 'email'. If the application uses
+ | another name for the field you may define it below as needed.
+ |
+ */
+
+ 'username' => 'email',
+
+ 'email' => 'email',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Home Path
+ |--------------------------------------------------------------------------
+ |
+ | Here you may configure the path where users will get redirected during
+ | authentication or password reset when the operations are successful
+ | and the user is authenticated. You are free to change this value.
+ |
+ */
+
+ 'home' => RouteServiceProvider::HOME,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Fortify Routes Prefix / Subdomain
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify which prefix Fortify will assign to all the routes
+ | that it registers with the application. If necessary, you may change
+ | subdomain under which all of the Fortify routes will be available.
+ |
+ */
+
+ 'prefix' => '',
+
+ 'domain' => null,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Fortify Routes Middleware
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify which middleware Fortify will assign to the routes
+ | that it registers with the application. If necessary, you may change
+ | these middleware but typically this provided default is preferred.
+ |
+ */
+
+ 'middleware' => ['web'],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Rate Limiting
+ |--------------------------------------------------------------------------
+ |
+ | By default, Fortify will throttle logins to five requests per minute for
+ | every email and IP address combination. However, if you would like to
+ | specify a custom rate limiter to call then you may specify it here.
+ |
+ */
+
+ 'limiters' => [
+ 'login' => 'login',
+ 'two-factor' => 'two-factor',
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Register View Routes
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify if the routes returning views should be disabled as
+ | you may not need them when building your own application. This may be
+ | especially true if you're writing a custom single-page application.
+ |
+ */
+
+ 'views' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Features
+ |--------------------------------------------------------------------------
+ |
+ | Some of the Fortify features are optional. You may disable the features
+ | by removing them from this array. You're free to only remove some of
+ | these features or you can even remove all of these if you need to.
+ |
+ */
+
+ 'features' => [
+ Features::registration(),
+ Features::resetPasswords(),
+ // Features::emailVerification(),
+ Features::updateProfileInformation(),
+ Features::updatePasswords(),
+ Features::twoFactorAuthentication([
+ 'confirm' => true,
+ 'confirmPassword' => true,
+ // 'window' => 0,
+ ]),
+ ],
+
+];
diff --git a/config/jetstream.php b/config/jetstream.php
new file mode 100644
index 0000000..e42c708
--- /dev/null
+++ b/config/jetstream.php
@@ -0,0 +1,81 @@
+ 'livewire',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Jetstream Route Middleware
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify which middleware Jetstream will assign to the routes
+ | that it registers with the application. When necessary, you may modify
+ | these middleware; however, this default value is usually sufficient.
+ |
+ */
+
+ 'middleware' => ['web'],
+
+ 'auth_session' => AuthenticateSession::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Jetstream Guard
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify the authentication guard Jetstream will use while
+ | authenticating users. This value should correspond with one of your
+ | guards that is already present in your "auth" configuration file.
+ |
+ */
+
+ 'guard' => 'sanctum',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Features
+ |--------------------------------------------------------------------------
+ |
+ | Some of Jetstream's features are optional. You may disable the features
+ | by removing them from this array. You're free to only remove some of
+ | these features or you can even remove all of these if you need to.
+ |
+ */
+
+ 'features' => [
+ // Features::termsAndPrivacyPolicy(),
+ Features::profilePhotos(),
+ // Features::api(),
+ Features::teams(['invitations' => true]),
+ Features::accountDeletion(),
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Profile Photo Disk
+ |--------------------------------------------------------------------------
+ |
+ | This configuration value determines the default disk that will be used
+ | when storing profile photos for your application's users. Typically
+ | this will be the "public" disk but you may adjust this if needed.
+ |
+ */
+
+ 'profile_photo_disk' => 'public',
+
+];
diff --git a/config/session.php b/config/session.php
index 8fed97c..cbcaf0b 100644
--- a/config/session.php
+++ b/config/session.php
@@ -18,7 +18,7 @@
|
*/
- 'driver' => env('SESSION_DRIVER', 'file'),
+ 'driver' => env('SESSION_DRIVER', 'database'),
/*
|--------------------------------------------------------------------------
diff --git a/database/factories/AsignacionFactory.php b/database/factories/AsignacionFactory.php
new file mode 100644
index 0000000..de61984
--- /dev/null
+++ b/database/factories/AsignacionFactory.php
@@ -0,0 +1,23 @@
+
+ */
+class AsignacionFactory extends Factory
+{
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition()
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/database/factories/CooperanteFactory.php b/database/factories/CooperanteFactory.php
new file mode 100644
index 0000000..3ee9b18
--- /dev/null
+++ b/database/factories/CooperanteFactory.php
@@ -0,0 +1,23 @@
+
+ */
+class CooperanteFactory extends Factory
+{
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition()
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/database/factories/ProyectoFactory.php b/database/factories/ProyectoFactory.php
new file mode 100644
index 0000000..52bdd3d
--- /dev/null
+++ b/database/factories/ProyectoFactory.php
@@ -0,0 +1,24 @@
+
+ */
+class ProyectoFactory extends Factory
+{
+ /**
+ * Define the model's default state.
+ *
+ * @return array
+ */
+ public function definition()
+ {
+ return [
+ 'nombre' => fake()->name(),
+ 'descripcion' => fake()->text(),
+ ];
+ }
+}
diff --git a/database/factories/TeamFactory.php b/database/factories/TeamFactory.php
new file mode 100644
index 0000000..abfd9d9
--- /dev/null
+++ b/database/factories/TeamFactory.php
@@ -0,0 +1,31 @@
+ $this->faker->unique()->company(),
+ 'user_id' => User::factory(),
+ 'personal_team' => true,
+ ];
+ }
+}
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index da6feab..8705898 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -2,24 +2,31 @@
namespace Database\Factories;
+use App\Models\Team;
+use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
+use Laravel\Jetstream\Features;
-/**
- * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
- */
class UserFactory extends Factory
{
+ /**
+ * The name of the factory's corresponding model.
+ *
+ * @var string
+ */
+ protected $model = User::class;
+
/**
* Define the model's default state.
*
- * @return array
+ * @return array
*/
public function definition()
{
return [
- 'name' => fake()->name(),
- 'email' => fake()->safeEmail(),
+ 'name' => $this->faker->name(),
+ 'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
@@ -29,12 +36,34 @@ public function definition()
/**
* Indicate that the model's email address should be unverified.
*
- * @return static
+ * @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function unverified()
{
- return $this->state(fn (array $attributes) => [
- 'email_verified_at' => null,
- ]);
+ return $this->state(function (array $attributes) {
+ return [
+ 'email_verified_at' => null,
+ ];
+ });
+ }
+
+ /**
+ * Indicate that the user should have a personal team.
+ *
+ * @return $this
+ */
+ public function withPersonalTeam()
+ {
+ if (! Features::hasTeamFeatures()) {
+ return $this->state([]);
+ }
+
+ return $this->has(
+ Team::factory()
+ ->state(function (array $attributes, User $user) {
+ return ['name' => $user->name.'\'s Team', 'user_id' => $user->id, 'personal_team' => true];
+ }),
+ 'ownedTeams'
+ );
}
}
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index cf6b776..84c648c 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -20,6 +20,8 @@ public function up()
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
+ $table->foreignId('current_team_id')->nullable();
+ $table->string('profile_photo_path', 2048)->nullable();
$table->timestamps();
});
}
diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php
new file mode 100644
index 0000000..6acbf7b
--- /dev/null
+++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php
@@ -0,0 +1,50 @@
+text('two_factor_secret')
+ ->after('password')
+ ->nullable();
+
+ $table->text('two_factor_recovery_codes')
+ ->after('two_factor_secret')
+ ->nullable();
+
+ if (Fortify::confirmsTwoFactorAuthentication()) {
+ $table->timestamp('two_factor_confirmed_at')
+ ->after('two_factor_recovery_codes')
+ ->nullable();
+ }
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dropColumn(array_merge([
+ 'two_factor_secret',
+ 'two_factor_recovery_codes',
+ ], Fortify::confirmsTwoFactorAuthentication() ? [
+ 'two_factor_confirmed_at',
+ ] : []));
+ });
+ }
+};
diff --git a/database/migrations/2020_05_21_100000_create_teams_table.php b/database/migrations/2020_05_21_100000_create_teams_table.php
new file mode 100644
index 0000000..7920ac9
--- /dev/null
+++ b/database/migrations/2020_05_21_100000_create_teams_table.php
@@ -0,0 +1,34 @@
+id();
+ $table->foreignId('user_id')->index();
+ $table->string('name');
+ $table->boolean('personal_team');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('teams');
+ }
+};
diff --git a/database/migrations/2020_05_21_200000_create_team_user_table.php b/database/migrations/2020_05_21_200000_create_team_user_table.php
new file mode 100644
index 0000000..20e1013
--- /dev/null
+++ b/database/migrations/2020_05_21_200000_create_team_user_table.php
@@ -0,0 +1,36 @@
+id();
+ $table->foreignId('team_id');
+ $table->foreignId('user_id');
+ $table->string('role')->nullable();
+ $table->timestamps();
+
+ $table->unique(['team_id', 'user_id']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('team_user');
+ }
+};
diff --git a/database/migrations/2020_05_21_300000_create_team_invitations_table.php b/database/migrations/2020_05_21_300000_create_team_invitations_table.php
new file mode 100644
index 0000000..b655e7a
--- /dev/null
+++ b/database/migrations/2020_05_21_300000_create_team_invitations_table.php
@@ -0,0 +1,36 @@
+id();
+ $table->foreignId('team_id')->constrained()->cascadeOnDelete();
+ $table->string('email');
+ $table->string('role')->nullable();
+ $table->timestamps();
+
+ $table->unique(['team_id', 'email']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('team_invitations');
+ }
+};
diff --git a/database/migrations/2022_09_06_045401_create_cooperantes_table.php b/database/migrations/2022_09_06_045401_create_cooperantes_table.php
new file mode 100644
index 0000000..1f05150
--- /dev/null
+++ b/database/migrations/2022_09_06_045401_create_cooperantes_table.php
@@ -0,0 +1,34 @@
+id();
+ $table->string('nombre')->unique();
+ $table->string('email')->unique();
+ $table->string('direccion');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('cooperantes');
+ }
+};
diff --git a/database/migrations/2022_09_06_045646_create_proyectos_table.php b/database/migrations/2022_09_06_045646_create_proyectos_table.php
new file mode 100644
index 0000000..dc0f6bb
--- /dev/null
+++ b/database/migrations/2022_09_06_045646_create_proyectos_table.php
@@ -0,0 +1,33 @@
+id();
+ $table->string('nombre')->unique();
+ $table->string('descripcion');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('proyectos');
+ }
+};
diff --git a/database/migrations/2022_09_06_045719_create_asignacions_table.php b/database/migrations/2022_09_06_045719_create_asignacions_table.php
new file mode 100644
index 0000000..42bb09d
--- /dev/null
+++ b/database/migrations/2022_09_06_045719_create_asignacions_table.php
@@ -0,0 +1,35 @@
+id();
+ $table->foreignId('cooperante_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate();
+ $table->foreignId('proyecto_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate();
+ $table->timestamp('fechaAsignacion');
+ $table->decimal('monto',9,2);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('asignacions');
+ }
+};
diff --git a/database/migrations/2022_10_06_044129_create_sessions_table.php b/database/migrations/2022_10_06_044129_create_sessions_table.php
new file mode 100644
index 0000000..06c3e45
--- /dev/null
+++ b/database/migrations/2022_10_06_044129_create_sessions_table.php
@@ -0,0 +1,35 @@
+string('id')->primary();
+ $table->foreignId('user_id')->nullable()->index();
+ $table->string('ip_address', 45)->nullable();
+ $table->text('user_agent')->nullable();
+ $table->longText('payload');
+ $table->integer('last_activity')->index();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('sessions');
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index 76d96dc..8f9197f 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -20,5 +20,7 @@ public function run()
// 'name' => 'Test User',
// 'email' => 'test@example.com',
// ]);
+
+ \App\Models\Proyecto::factory(10)->create();
}
}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..7d064a2
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2607 @@
+{
+ "name": "ejercicio",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "@tailwindcss/forms": "^0.5.2",
+ "@tailwindcss/typography": "^0.5.0",
+ "alpinejs": "^3.0.6",
+ "autoprefixer": "^10.4.7",
+ "axios": "^0.27",
+ "bootstrap": "^5.2.1",
+ "laravel-vite-plugin": "^0.5.0",
+ "lodash": "^4.17.19",
+ "postcss": "^8.4.14",
+ "tailwindcss": "^3.1.0",
+ "vite": "^3.0.0"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz",
+ "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz",
+ "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "dev": true,
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@tailwindcss/forms": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz",
+ "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==",
+ "dev": true,
+ "dependencies": {
+ "mini-svg-data-uri": "^1.2.3"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
+ }
+ },
+ "node_modules/@tailwindcss/typography": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.7.tgz",
+ "integrity": "sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==",
+ "dev": true,
+ "dependencies": {
+ "lodash.castarray": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "postcss-selector-parser": "6.0.10"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || insiders"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
+ "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
+ "dev": true,
+ "dependencies": {
+ "@vue/shared": "3.1.5"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
+ "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/alpinejs": {
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.10.3.tgz",
+ "integrity": "sha512-nt/w4hLq9pPaexCsHmO5zV5Alvq4yu9n0Iclti6aV0HmiqLWH/axUb0pn8z3XVuVNcj8EOXOQw+WpwPzMzLBWg==",
+ "dev": true,
+ "dependencies": {
+ "@vue/reactivity": "~3.1.1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.12",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz",
+ "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-lite": "^1.0.30001407",
+ "fraction.js": "^4.2.0",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dev": true,
+ "dependencies": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bootstrap": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.1.tgz",
+ "integrity": "sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.6"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001416",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001416.tgz",
+ "integrity": "sha512-06wzzdAkCPZO+Qm4e/eNghZBDfVNDsCgw33T27OwBH9unE9S478OYw//Q2L7Npf/zBzs7rjZOszIFQkwQKAEqA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==",
+ "dev": true
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/detective": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
+ "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
+ "dev": true,
+ "dependencies": {
+ "acorn-node": "^1.8.2",
+ "defined": "^1.0.0",
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "detective": "bin/detective.js"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.274",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.274.tgz",
+ "integrity": "sha512-Fgn7JZQzq85I81FpKUNxVLAzoghy8JZJ4NIue+YfUYBbu1AkpgzFvNwzF/ZNZH9ElkmJD0TSWu1F2gTpw/zZlg==",
+ "dev": true
+ },
+ "node_modules/esbuild": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz",
+ "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.15.10",
+ "@esbuild/linux-loong64": "0.15.10",
+ "esbuild-android-64": "0.15.10",
+ "esbuild-android-arm64": "0.15.10",
+ "esbuild-darwin-64": "0.15.10",
+ "esbuild-darwin-arm64": "0.15.10",
+ "esbuild-freebsd-64": "0.15.10",
+ "esbuild-freebsd-arm64": "0.15.10",
+ "esbuild-linux-32": "0.15.10",
+ "esbuild-linux-64": "0.15.10",
+ "esbuild-linux-arm": "0.15.10",
+ "esbuild-linux-arm64": "0.15.10",
+ "esbuild-linux-mips64le": "0.15.10",
+ "esbuild-linux-ppc64le": "0.15.10",
+ "esbuild-linux-riscv64": "0.15.10",
+ "esbuild-linux-s390x": "0.15.10",
+ "esbuild-netbsd-64": "0.15.10",
+ "esbuild-openbsd-64": "0.15.10",
+ "esbuild-sunos-64": "0.15.10",
+ "esbuild-windows-32": "0.15.10",
+ "esbuild-windows-64": "0.15.10",
+ "esbuild-windows-arm64": "0.15.10"
+ }
+ },
+ "node_modules/esbuild-android-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz",
+ "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-android-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz",
+ "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz",
+ "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz",
+ "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz",
+ "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz",
+ "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-32": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz",
+ "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz",
+ "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz",
+ "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz",
+ "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-mips64le": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz",
+ "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-ppc64le": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz",
+ "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-riscv64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz",
+ "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-s390x": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz",
+ "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-netbsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz",
+ "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-openbsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz",
+ "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-sunos-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz",
+ "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-32": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz",
+ "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz",
+ "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz",
+ "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.12",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
+ "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://www.patreon.com/infusion"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/laravel-vite-plugin": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.5.4.tgz",
+ "integrity": "sha512-LSLLul+YwY3egz0fzO4TPEGtUQAL4F2hrrt5wfQo3OzUfjVrqtRy0w1Zkw/g8CkfUyAZhr59oc/RxvPmpF9czg==",
+ "dev": true,
+ "dependencies": {
+ "vite-plugin-full-reload": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "vite": "^3.0.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
+ "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.castarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
+ "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
+ "dev": true
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "dev": true,
+ "bin": {
+ "mini-svg-data-uri": "cli.js"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+ "dev": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.17",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
+ "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.4",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz",
+ "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
+ "dev": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
+ "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3.3"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
+ "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+ "dev": true,
+ "dependencies": {
+ "lilconfig": "^2.0.5",
+ "yaml": "^1.10.2"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
+ "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.6"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.78.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
+ "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz",
+ "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==",
+ "dev": true,
+ "dependencies": {
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "color-name": "^1.1.4",
+ "detective": "^5.2.1",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.2.11",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "lilconfig": "^2.0.6",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.14",
+ "postcss-import": "^14.1.0",
+ "postcss-js": "^4.0.0",
+ "postcss-load-config": "^3.1.4",
+ "postcss-nested": "5.0.6",
+ "postcss-selector-parser": "^6.0.10",
+ "postcss-value-parser": "^4.2.0",
+ "quick-lru": "^5.1.1",
+ "resolve": "^1.22.1"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/vite": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.4.tgz",
+ "integrity": "sha512-JoQI08aBjY9lycL7jcEq4p9o1xUjq5aRvdH4KWaXtkSx7e7RpAh9D3IjzDWRD4Fg44LS3oDAIOG/Kq1L+82psA==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.15.6",
+ "postcss": "^8.4.16",
+ "resolve": "^1.22.1",
+ "rollup": "~2.78.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-full-reload": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.0.4.tgz",
+ "integrity": "sha512-9WejQII6zJ++m/YE173Zvl2jq4cqa404KNrVT+JDzDnqaGRq5UvOvA48fnsSWPIMXFV7S0dq5+sZqcSB+tKBgA==",
+ "dev": true,
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "picomatch": "^2.3.1"
+ },
+ "peerDependencies": {
+ "vite": "^2 || ^3"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ }
+ },
+ "dependencies": {
+ "@esbuild/android-arm": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz",
+ "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-loong64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz",
+ "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==",
+ "dev": true,
+ "optional": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "dev": true,
+ "peer": true
+ },
+ "@tailwindcss/forms": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz",
+ "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==",
+ "dev": true,
+ "requires": {
+ "mini-svg-data-uri": "^1.2.3"
+ }
+ },
+ "@tailwindcss/typography": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.7.tgz",
+ "integrity": "sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==",
+ "dev": true,
+ "requires": {
+ "lodash.castarray": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "postcss-selector-parser": "6.0.10"
+ }
+ },
+ "@vue/reactivity": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
+ "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
+ "dev": true,
+ "requires": {
+ "@vue/shared": "3.1.5"
+ }
+ },
+ "@vue/shared": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
+ "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
+ "alpinejs": {
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.10.3.tgz",
+ "integrity": "sha512-nt/w4hLq9pPaexCsHmO5zV5Alvq4yu9n0Iclti6aV0HmiqLWH/axUb0pn8z3XVuVNcj8EOXOQw+WpwPzMzLBWg==",
+ "dev": true,
+ "requires": {
+ "@vue/reactivity": "~3.1.1"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "10.4.12",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz",
+ "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.21.4",
+ "caniuse-lite": "^1.0.30001407",
+ "fraction.js": "^4.2.0",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.0",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
+ "axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dev": true,
+ "requires": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "bootstrap": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.1.tgz",
+ "integrity": "sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA==",
+ "dev": true,
+ "requires": {}
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ }
+ },
+ "camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001416",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001416.tgz",
+ "integrity": "sha512-06wzzdAkCPZO+Qm4e/eNghZBDfVNDsCgw33T27OwBH9unE9S478OYw//Q2L7Npf/zBzs7rjZOszIFQkwQKAEqA==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true
+ },
+ "detective": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
+ "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.8.2",
+ "defined": "^1.0.0",
+ "minimist": "^1.2.6"
+ }
+ },
+ "didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "dev": true
+ },
+ "dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.4.274",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.274.tgz",
+ "integrity": "sha512-Fgn7JZQzq85I81FpKUNxVLAzoghy8JZJ4NIue+YfUYBbu1AkpgzFvNwzF/ZNZH9ElkmJD0TSWu1F2gTpw/zZlg==",
+ "dev": true
+ },
+ "esbuild": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz",
+ "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==",
+ "dev": true,
+ "requires": {
+ "@esbuild/android-arm": "0.15.10",
+ "@esbuild/linux-loong64": "0.15.10",
+ "esbuild-android-64": "0.15.10",
+ "esbuild-android-arm64": "0.15.10",
+ "esbuild-darwin-64": "0.15.10",
+ "esbuild-darwin-arm64": "0.15.10",
+ "esbuild-freebsd-64": "0.15.10",
+ "esbuild-freebsd-arm64": "0.15.10",
+ "esbuild-linux-32": "0.15.10",
+ "esbuild-linux-64": "0.15.10",
+ "esbuild-linux-arm": "0.15.10",
+ "esbuild-linux-arm64": "0.15.10",
+ "esbuild-linux-mips64le": "0.15.10",
+ "esbuild-linux-ppc64le": "0.15.10",
+ "esbuild-linux-riscv64": "0.15.10",
+ "esbuild-linux-s390x": "0.15.10",
+ "esbuild-netbsd-64": "0.15.10",
+ "esbuild-openbsd-64": "0.15.10",
+ "esbuild-sunos-64": "0.15.10",
+ "esbuild-windows-32": "0.15.10",
+ "esbuild-windows-64": "0.15.10",
+ "esbuild-windows-arm64": "0.15.10"
+ }
+ },
+ "esbuild-android-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz",
+ "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-android-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz",
+ "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-darwin-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz",
+ "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-darwin-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz",
+ "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-freebsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz",
+ "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-freebsd-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz",
+ "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-32": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz",
+ "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz",
+ "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-arm": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz",
+ "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz",
+ "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-mips64le": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz",
+ "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-ppc64le": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz",
+ "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-riscv64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz",
+ "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-linux-s390x": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz",
+ "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-netbsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz",
+ "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-openbsd-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz",
+ "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-sunos-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz",
+ "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-windows-32": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz",
+ "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-windows-64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz",
+ "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==",
+ "dev": true,
+ "optional": true
+ },
+ "esbuild-windows-arm64": {
+ "version": "0.15.10",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz",
+ "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==",
+ "dev": true,
+ "optional": true
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.12",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
+ }
+ },
+ "fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "dev": true
+ },
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fraction.js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
+ "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "laravel-vite-plugin": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.5.4.tgz",
+ "integrity": "sha512-LSLLul+YwY3egz0fzO4TPEGtUQAL4F2hrrt5wfQo3OzUfjVrqtRy0w1Zkw/g8CkfUyAZhr59oc/RxvPmpF9czg==",
+ "dev": true,
+ "requires": {
+ "vite-plugin-full-reload": "^1.0.1"
+ }
+ },
+ "lilconfig": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
+ "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
+ "dev": true
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash.castarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
+ "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
+ "dev": true
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.52.0"
+ }
+ },
+ "mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
+ },
+ "nanoid": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true
+ },
+ "object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "8.4.17",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
+ "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
+ "dev": true,
+ "requires": {
+ "nanoid": "^3.3.4",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ }
+ },
+ "postcss-import": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz",
+ "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
+ "dev": true,
+ "requires": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
+ "postcss-js": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
+ "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==",
+ "dev": true,
+ "requires": {
+ "camelcase-css": "^2.0.1"
+ }
+ },
+ "postcss-load-config": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
+ "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+ "dev": true,
+ "requires": {
+ "lilconfig": "^2.0.5",
+ "yaml": "^1.10.2"
+ }
+ },
+ "postcss-nested": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
+ "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.6"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true
+ },
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^2.3.0"
+ }
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rollup": {
+ "version": "2.78.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
+ "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
+ "dev": true,
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "tailwindcss": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz",
+ "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==",
+ "dev": true,
+ "requires": {
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "color-name": "^1.1.4",
+ "detective": "^5.2.1",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.2.11",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "lilconfig": "^2.0.6",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.14",
+ "postcss-import": "^14.1.0",
+ "postcss-js": "^4.0.0",
+ "postcss-load-config": "^3.1.4",
+ "postcss-nested": "5.0.6",
+ "postcss-selector-parser": "^6.0.10",
+ "postcss-value-parser": "^4.2.0",
+ "quick-lru": "^5.1.1",
+ "resolve": "^1.22.1"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "requires": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "vite": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.4.tgz",
+ "integrity": "sha512-JoQI08aBjY9lycL7jcEq4p9o1xUjq5aRvdH4KWaXtkSx7e7RpAh9D3IjzDWRD4Fg44LS3oDAIOG/Kq1L+82psA==",
+ "dev": true,
+ "requires": {
+ "esbuild": "^0.15.6",
+ "fsevents": "~2.3.2",
+ "postcss": "^8.4.16",
+ "resolve": "^1.22.1",
+ "rollup": "~2.78.0"
+ }
+ },
+ "vite-plugin-full-reload": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.0.4.tgz",
+ "integrity": "sha512-9WejQII6zJ++m/YE173Zvl2jq4cqa404KNrVT+JDzDnqaGRq5UvOvA48fnsSWPIMXFV7S0dq5+sZqcSB+tKBgA==",
+ "dev": true,
+ "requires": {
+ "picocolors": "^1.0.0",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
+ "yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index 6267eac..0b2ccab 100644
--- a/package.json
+++ b/package.json
@@ -5,10 +5,16 @@
"build": "vite build"
},
"devDependencies": {
+ "@tailwindcss/forms": "^0.5.2",
+ "@tailwindcss/typography": "^0.5.0",
+ "alpinejs": "^3.0.6",
+ "autoprefixer": "^10.4.7",
"axios": "^0.27",
+ "bootstrap": "^5.2.1",
"laravel-vite-plugin": "^0.5.0",
"lodash": "^4.17.19",
- "postcss": "^8.1.14",
+ "postcss": "^8.4.14",
+ "tailwindcss": "^3.1.0",
"vite": "^3.0.0"
}
}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..67cdf1a
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/resources/css/app.css b/resources/css/app.css
index e69de29..b5c61c9 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/resources/js/app.js b/resources/js/app.js
index e59d6a0..a8093be 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1 +1,7 @@
import './bootstrap';
+
+import Alpine from 'alpinejs';
+
+window.Alpine = Alpine;
+
+Alpine.start();
diff --git a/resources/markdown/policy.md b/resources/markdown/policy.md
new file mode 100644
index 0000000..ff7dbea
--- /dev/null
+++ b/resources/markdown/policy.md
@@ -0,0 +1,3 @@
+# Privacy Policy
+
+Edit this file to define the privacy policy for your application.
diff --git a/resources/markdown/terms.md b/resources/markdown/terms.md
new file mode 100644
index 0000000..bf2ace7
--- /dev/null
+++ b/resources/markdown/terms.md
@@ -0,0 +1,3 @@
+# Terms of Service
+
+Edit this file to define the terms of service for your application.
diff --git a/resources/views/api/api-token-manager.blade.php b/resources/views/api/api-token-manager.blade.php
new file mode 100644
index 0000000..1391fb7
--- /dev/null
+++ b/resources/views/api/api-token-manager.blade.php
@@ -0,0 +1,169 @@
+
+
+
+
+ {{ __('Create API Token') }}
+
+
+
+ {{ __('API tokens allow third-party services to authenticate with our application on your behalf.') }}
+
+
+
+
+
+
+
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::hasPermissions())
+
+
+
+
+ @foreach (Laravel\Jetstream\Jetstream::$permissions as $permission)
+
+
+ {{ $permission }}
+
+ @endforeach
+
+
+ @endif
+
+
+
+
+ {{ __('Created.') }}
+
+
+
+ {{ __('Create') }}
+
+
+
+
+ @if ($this->user->tokens->isNotEmpty())
+
+
+
+
+
+
+ {{ __('Manage API Tokens') }}
+
+
+
+ {{ __('You may delete any of your existing tokens if they are no longer needed.') }}
+
+
+
+
+
+ @foreach ($this->user->tokens->sortBy('name') as $token)
+
+
+ {{ $token->name }}
+
+
+
+ @if ($token->last_used_at)
+
+ {{ __('Last used') }} {{ $token->last_used_at->diffForHumans() }}
+
+ @endif
+
+ @if (Laravel\Jetstream\Jetstream::hasPermissions())
+
+ {{ __('Permissions') }}
+
+ @endif
+
+
+ {{ __('Delete') }}
+
+
+
+ @endforeach
+
+
+
+
+ @endif
+
+
+
+
+ {{ __('API Token') }}
+
+
+
+
+ {{ __('Please copy your new API token. For your security, it won\'t be shown again.') }}
+
+
+ $refs.plaintextToken.select(), 250)"
+ />
+
+
+
+
+ {{ __('Close') }}
+
+
+
+
+
+
+
+ {{ __('API Token Permissions') }}
+
+
+
+
+ @foreach (Laravel\Jetstream\Jetstream::$permissions as $permission)
+
+
+ {{ $permission }}
+
+ @endforeach
+
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Save') }}
+
+
+
+
+
+
+
+ {{ __('Delete API Token') }}
+
+
+
+ {{ __('Are you sure you would like to delete this API token?') }}
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Delete') }}
+
+
+
+
diff --git a/resources/views/api/index.blade.php b/resources/views/api/index.blade.php
new file mode 100644
index 0000000..d15b6a3
--- /dev/null
+++ b/resources/views/api/index.blade.php
@@ -0,0 +1,13 @@
+
+
+
+ {{ __('API Tokens') }}
+
+
+
+
+
+ @livewire('api.api-token-manager')
+
+
+
diff --git a/resources/views/asignaciones/create.blade.php b/resources/views/asignaciones/create.blade.php
new file mode 100644
index 0000000..54c6492
--- /dev/null
+++ b/resources/views/asignaciones/create.blade.php
@@ -0,0 +1,57 @@
+@extends('layouts.plantilla')
+
+@section('title','Crear Proyecto')
+
+@section('content')
+
+ Crear nuevo Proyecto
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/asignaciones/edit.blade.php b/resources/views/asignaciones/edit.blade.php
new file mode 100644
index 0000000..dade32e
--- /dev/null
+++ b/resources/views/asignaciones/edit.blade.php
@@ -0,0 +1,58 @@
+@extends('layouts.plantilla')
+
+@section('title','Editar Asignacion')
+
+@section('content')
+
+ Editar Asignación
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/asignaciones/index.blade.php b/resources/views/asignaciones/index.blade.php
new file mode 100644
index 0000000..2f4c36b
--- /dev/null
+++ b/resources/views/asignaciones/index.blade.php
@@ -0,0 +1,92 @@
+@extends('layouts.plantilla')
+
+@section('title','Asignaciones')
+
+@section('content')
+
+ Asignaciones
+
+ Crear nueva Asignación
+
+ @if(session('status'))
+
+
+ {{ session('status') }}
+
+ @else
+
+ @endif
+
+
+ Seleccionar Cooperante:
+
+ --- Todos ---
+ @isset($cooperantes)
+ @foreach($cooperantes as $item){ ?>
+
+ {{ $item->nombre }}
+
+ @endforeach
+ @endisset
+
+
+ Buscar Reporte
+
+
+
+
+
+ N.
+ Cooperante
+ Proyecto
+ Fecha Asignación
+ Monto
+ Editar
+
+
+
+ @forelse($asignaciones as $asignacion)
+
+ {{$asignacion->id}}
+ {{$asignacion->cooperante->nombre}}
+ {{$asignacion->proyecto->nombre}}
+ {{$asignacion->fechaAsignacion->format('d/m/Y')}}
+ @money($asignacion->monto)
+ EDITAR
+
+
+ @empty
+ No hay Proyectos para mostrar
+ @endforelse
+
+
+
+
+
+ Total
+ @money($asignaciones->sum('monto'))
+
+
+
+
+
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/auth/confirm-password.blade.php b/resources/views/auth/confirm-password.blade.php
new file mode 100644
index 0000000..d87049a
--- /dev/null
+++ b/resources/views/auth/confirm-password.blade.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+ {{ __('This is a secure area of the application. Please confirm your password before continuing.') }}
+
+
+
+
+
+
+
diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php
new file mode 100644
index 0000000..6af4ab6
--- /dev/null
+++ b/resources/views/auth/forgot-password.blade.php
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+ {{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
+
+
+ @if (session('status'))
+
+ {{ session('status') }}
+
+ @endif
+
+
+
+
+
+
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php
new file mode 100644
index 0000000..e62d8d3
--- /dev/null
+++ b/resources/views/auth/login.blade.php
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+ @if (session('status'))
+
+ {{ session('status') }}
+
+ @endif
+
+
+
+
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php
new file mode 100644
index 0000000..d0a58ea
--- /dev/null
+++ b/resources/views/auth/register.blade.php
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php
new file mode 100644
index 0000000..36a9f65
--- /dev/null
+++ b/resources/views/auth/reset-password.blade.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php
new file mode 100644
index 0000000..6d54913
--- /dev/null
+++ b/resources/views/auth/two-factor-challenge.blade.php
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+ {{ __('Please confirm access to your account by entering the authentication code provided by your authenticator application.') }}
+
+
+
+ {{ __('Please confirm access to your account by entering one of your emergency recovery codes.') }}
+
+
+
+
+
+
+
+
diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php
new file mode 100644
index 0000000..7e61646
--- /dev/null
+++ b/resources/views/auth/verify-email.blade.php
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+ {{ __('Before continuing, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
+
+
+ @if (session('status') == 'verification-link-sent')
+
+ {{ __('A new verification link has been sent to the email address you provided in your profile settings.') }}
+
+ @endif
+
+
+
+
diff --git a/resources/views/cooperantes/_form.blade.php b/resources/views/cooperantes/_form.blade.php
new file mode 100644
index 0000000..b0b2cbd
--- /dev/null
+++ b/resources/views/cooperantes/_form.blade.php
@@ -0,0 +1,19 @@
+@csrf
+
+
+ Nombre
+
+
+
+
+ Email
+
+
+
+
+ Direccion
+
+
+
+
+ {{ $btnText }}
\ No newline at end of file
diff --git a/resources/views/cooperantes/create.blade.php b/resources/views/cooperantes/create.blade.php
new file mode 100644
index 0000000..003ba65
--- /dev/null
+++ b/resources/views/cooperantes/create.blade.php
@@ -0,0 +1,17 @@
+@extends('layouts.plantilla')
+
+@section('title','Crear Cooperante')
+
+@section('content')
+
+ Crear nuevo Cooperante
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/cooperantes/edit.blade.php b/resources/views/cooperantes/edit.blade.php
new file mode 100644
index 0000000..50dee00
--- /dev/null
+++ b/resources/views/cooperantes/edit.blade.php
@@ -0,0 +1,18 @@
+@extends('layouts.plantilla')
+
+@section('title','Editar Cooperante')
+
+@section('content')
+
+ Editar Cooperante
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/cooperantes/index.blade.php b/resources/views/cooperantes/index.blade.php
new file mode 100644
index 0000000..5b9e9c2
--- /dev/null
+++ b/resources/views/cooperantes/index.blade.php
@@ -0,0 +1,48 @@
+@extends('layouts.plantilla')
+
+@section('title','Cooperantes')
+
+@section('content')
+
+ Cooperantes
+
+ Crear Cooperante
+
+ @if(session('status'))
+
+
+ {{ session('status') }}
+
+ @else
+
+ @endif
+
+
+
+
+ ID
+ Nombre
+ Email
+ Fecha modificación
+ Ver
+
+
+
+ @forelse($cooperantes as $item)
+
+ {{$item->id}}
+ {{ $item->nombre }}
+ {{ $item->email }}
+ {{ $item->updated_at->format('d/m/Y') }}
+ VER
+
+ @empty
+
+ No hay Cooperantes para mostrar
+
+ @endforelse
+
+
+ {{ $cooperantes->links() }}
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/cooperantes/show.blade.php b/resources/views/cooperantes/show.blade.php
new file mode 100644
index 0000000..c47c702
--- /dev/null
+++ b/resources/views/cooperantes/show.blade.php
@@ -0,0 +1,54 @@
+@extends('layouts.plantilla')
+
+@section('title', 'Cooperante | '.$cooperante->nombre)
+
+@section('content')
+
+ Consultar Cooperante
+
+
+
+
+
+
+
+
+
+ Editar
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php
new file mode 100644
index 0000000..0d0c9c9
--- /dev/null
+++ b/resources/views/dashboard.blade.php
@@ -0,0 +1,15 @@
+
+
+
+ {{ __('Dashboard') }}
+
+
+
+
+
diff --git a/resources/views/inicio.blade.php b/resources/views/inicio.blade.php
index 66ade82..5c77510 100644
--- a/resources/views/inicio.blade.php
+++ b/resources/views/inicio.blade.php
@@ -1,71 +1,12 @@
-
-
-
-
-
+@extends('layouts.plantilla')
- Laravel
+@section('title','Proyectos')
-
-
+@section('content')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Agregar enlaces para el ejercicio:
- -Catálogos
- -Reporte
- -Otros enlaces que considere necesario
-
-
-
-
-
-
-
-
-
- Ejercicio LARAVEL
-
-
-
-
- ELA 2022.-
-
-
-
-
-
-
+{{-- Agregar enlaces para el ejercicio:
+-Catálogos
+-Reporte
+-Otros enlaces que considere necesario --}}
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
new file mode 100644
index 0000000..7fd3e8f
--- /dev/null
+++ b/resources/views/layouts/app.blade.php
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ {{ config('app.name', 'Laravel') }}
+
+
+
+
+
+ @vite(['resources/css/app.css', 'resources/js/app.js'])
+
+
+ @livewireStyles
+
+
+
+
+
+ @livewire('navigation-menu')
+
+
+ @if (isset($header))
+
+ @endif
+
+
+
+ {{ $slot }}
+
+
+
+ @stack('modals')
+
+ @livewireScripts
+
+
diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php
new file mode 100644
index 0000000..a5ec1c3
--- /dev/null
+++ b/resources/views/layouts/guest.blade.php
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ {{ config('app.name', 'Laravel') }}
+
+
+
+
+
+ @vite(['resources/css/app.css', 'resources/js/app.js'])
+
+
+
+ {{ $slot }}
+
+
+
diff --git a/resources/views/layouts/plantilla.blade.php b/resources/views/layouts/plantilla.blade.php
new file mode 100644
index 0000000..8daa250
--- /dev/null
+++ b/resources/views/layouts/plantilla.blade.php
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+ Laravel
+
+ {{-- @vite(['resources/css/app.css','resources/js/app.js']) --}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Prueba de Carlos Eduardo Fuentes Romero
+
+ @include('partials.nav')
+
+
+
+
+
+
+
+
+
+
+
+
+ @yield('content')
+
+
+
+
+
+
+
+
+
+ Ejercicio LARAVEL
+
+
+
+
+ ELA 2022.-
+
+
+
+
+
+
diff --git a/resources/views/navigation-menu.blade.php b/resources/views/navigation-menu.blade.php
new file mode 100644
index 0000000..9ce13ca
--- /dev/null
+++ b/resources/views/navigation-menu.blade.php
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Dashboard') }}
+
+
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::hasTeamFeatures())
+
+
+
+
+
+ {{ Auth::user()->currentTeam->name }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Manage Team') }}
+
+
+
+
+ {{ __('Team Settings') }}
+
+
+ @can('create', Laravel\Jetstream\Jetstream::newTeamModel())
+
+ {{ __('Create New Team') }}
+
+ @endcan
+
+
+
+
+
+ {{ __('Switch Teams') }}
+
+
+ @foreach (Auth::user()->allTeams() as $team)
+
+ @endforeach
+
+
+
+
+ @endif
+
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
+
+
+
+ @else
+
+
+ {{ Auth::user()->name }}
+
+
+
+
+
+
+ @endif
+
+
+
+
+
+ {{ __('Manage Account') }}
+
+
+
+ {{ __('Profile') }}
+
+
+ @if (Laravel\Jetstream\Jetstream::hasApiFeatures())
+
+ {{ __('API Tokens') }}
+
+ @endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Dashboard') }}
+
+
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
+
+
+
+ @endif
+
+
+
{{ Auth::user()->name }}
+
{{ Auth::user()->email }}
+
+
+
+
+
+
+ {{ __('Profile') }}
+
+
+ @if (Laravel\Jetstream\Jetstream::hasApiFeatures())
+
+ {{ __('API Tokens') }}
+
+ @endif
+
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::hasTeamFeatures())
+
+
+
+ {{ __('Manage Team') }}
+
+
+
+
+ {{ __('Team Settings') }}
+
+
+ @can('create', Laravel\Jetstream\Jetstream::newTeamModel())
+
+ {{ __('Create New Team') }}
+
+ @endcan
+
+
+
+
+
+ {{ __('Switch Teams') }}
+
+
+ @foreach (Auth::user()->allTeams() as $team)
+
+ @endforeach
+ @endif
+
+
+
+
diff --git a/resources/views/partials/nav.blade.php b/resources/views/partials/nav.blade.php
new file mode 100644
index 0000000..6a6653b
--- /dev/null
+++ b/resources/views/partials/nav.blade.php
@@ -0,0 +1,38 @@
+
+
+ {{-- {{ dump(request()->routeIs('home')) }} --}}
+
+
+
\ No newline at end of file
diff --git a/resources/views/partials/session-status.blade.php b/resources/views/partials/session-status.blade.php
new file mode 100644
index 0000000..02d40d6
--- /dev/null
+++ b/resources/views/partials/session-status.blade.php
@@ -0,0 +1,3 @@
+@if(session('status'))
+ {{ session('status') }}
+@endif
\ No newline at end of file
diff --git a/resources/views/partials/validation-errors.blade.php b/resources/views/partials/validation-errors.blade.php
new file mode 100644
index 0000000..65b731a
--- /dev/null
+++ b/resources/views/partials/validation-errors.blade.php
@@ -0,0 +1,9 @@
+@if($errors->any())
+
+
+ @foreach($errors->all() as $error)
+ {{ $error }}
+ @endforeach
+
+
+@endif
\ No newline at end of file
diff --git a/resources/views/policy.blade.php b/resources/views/policy.blade.php
new file mode 100644
index 0000000..17e1359
--- /dev/null
+++ b/resources/views/policy.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ {!! $policy !!}
+
+
+
+
diff --git a/resources/views/profile/delete-user-form.blade.php b/resources/views/profile/delete-user-form.blade.php
new file mode 100644
index 0000000..3acdb30
--- /dev/null
+++ b/resources/views/profile/delete-user-form.blade.php
@@ -0,0 +1,52 @@
+
+
+ {{ __('Delete Account') }}
+
+
+
+ {{ __('Permanently delete your account.') }}
+
+
+
+
+ {{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
+
+
+
+
+ {{ __('Delete Account') }}
+
+
+
+
+
+
+ {{ __('Delete Account') }}
+
+
+
+ {{ __('Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
+
+
+
+
+
+
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Delete Account') }}
+
+
+
+
+
diff --git a/resources/views/profile/logout-other-browser-sessions-form.blade.php b/resources/views/profile/logout-other-browser-sessions-form.blade.php
new file mode 100644
index 0000000..c20b465
--- /dev/null
+++ b/resources/views/profile/logout-other-browser-sessions-form.blade.php
@@ -0,0 +1,97 @@
+
+
+ {{ __('Browser Sessions') }}
+
+
+
+ {{ __('Manage and log out your active sessions on other browsers and devices.') }}
+
+
+
+
+ {{ __('If necessary, you may log out of all of your other browser sessions across all of your devices. Some of your recent sessions are listed below; however, this list may not be exhaustive. If you feel your account has been compromised, you should also update your password.') }}
+
+
+ @if (count($this->sessions) > 0)
+
+
+ @foreach ($this->sessions as $session)
+
+
+ @if ($session->agent->isDesktop())
+
+
+
+ @else
+
+
+
+ @endif
+
+
+
+
+ {{ $session->agent->platform() ? $session->agent->platform() : 'Unknown' }} - {{ $session->agent->browser() ? $session->agent->browser() : 'Unknown' }}
+
+
+
+
+ {{ $session->ip_address }},
+
+ @if ($session->is_current_device)
+ {{ __('This device') }}
+ @else
+ {{ __('Last active') }} {{ $session->last_active }}
+ @endif
+
+
+
+
+ @endforeach
+
+ @endif
+
+
+
+ {{ __('Log Out Other Browser Sessions') }}
+
+
+
+ {{ __('Done.') }}
+
+
+
+
+
+
+ {{ __('Log Out Other Browser Sessions') }}
+
+
+
+ {{ __('Please enter your password to confirm you would like to log out of your other browser sessions across all of your devices.') }}
+
+
+
+
+
+
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Log Out Other Browser Sessions') }}
+
+
+
+
+
diff --git a/resources/views/profile/show.blade.php b/resources/views/profile/show.blade.php
new file mode 100644
index 0000000..b8a7995
--- /dev/null
+++ b/resources/views/profile/show.blade.php
@@ -0,0 +1,45 @@
+
+
+
+ {{ __('Profile') }}
+
+
+
+
+
+ @if (Laravel\Fortify\Features::canUpdateProfileInformation())
+ @livewire('profile.update-profile-information-form')
+
+
+ @endif
+
+ @if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::updatePasswords()))
+
+ @livewire('profile.update-password-form')
+
+
+
+ @endif
+
+ @if (Laravel\Fortify\Features::canManageTwoFactorAuthentication())
+
+ @livewire('profile.two-factor-authentication-form')
+
+
+
+ @endif
+
+
+ @livewire('profile.logout-other-browser-sessions-form')
+
+
+ @if (Laravel\Jetstream\Jetstream::hasAccountDeletionFeatures())
+
+
+
+ @livewire('profile.delete-user-form')
+
+ @endif
+
+
+
diff --git a/resources/views/profile/two-factor-authentication-form.blade.php b/resources/views/profile/two-factor-authentication-form.blade.php
new file mode 100644
index 0000000..5dc8fbe
--- /dev/null
+++ b/resources/views/profile/two-factor-authentication-form.blade.php
@@ -0,0 +1,124 @@
+
+
+ {{ __('Two Factor Authentication') }}
+
+
+
+ {{ __('Add additional security to your account using two factor authentication.') }}
+
+
+
+
+ @if ($this->enabled)
+ @if ($showingConfirmation)
+ {{ __('Finish enabling two factor authentication.') }}
+ @else
+ {{ __('You have enabled two factor authentication.') }}
+ @endif
+ @else
+ {{ __('You have not enabled two factor authentication.') }}
+ @endif
+
+
+
+
+ {{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.') }}
+
+
+
+ @if ($this->enabled)
+ @if ($showingQrCode)
+
+
+ @if ($showingConfirmation)
+ {{ __('To finish enabling two factor authentication, scan the following QR code using your phone\'s authenticator application or enter the setup key and provide the generated OTP code.') }}
+ @else
+ {{ __('Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application or enter the setup key.') }}
+ @endif
+
+
+
+
+ {!! $this->user->twoFactorQrCodeSvg() !!}
+
+
+
+
+ {{ __('Setup Key') }}: {{ decrypt($this->user->two_factor_secret) }}
+
+
+
+ @if ($showingConfirmation)
+
+
+
+
+
+
+
+ @endif
+ @endif
+
+ @if ($showingRecoveryCodes)
+
+
+ {{ __('Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.') }}
+
+
+
+
+ @foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as $code)
+
{{ $code }}
+ @endforeach
+
+ @endif
+ @endif
+
+
+ @if (! $this->enabled)
+
+
+ {{ __('Enable') }}
+
+
+ @else
+ @if ($showingRecoveryCodes)
+
+
+ {{ __('Regenerate Recovery Codes') }}
+
+
+ @elseif ($showingConfirmation)
+
+
+ {{ __('Confirm') }}
+
+
+ @else
+
+
+ {{ __('Show Recovery Codes') }}
+
+
+ @endif
+
+ @if ($showingConfirmation)
+
+
+ {{ __('Cancel') }}
+
+
+ @else
+
+
+ {{ __('Disable') }}
+
+
+ @endif
+
+ @endif
+
+
+
diff --git a/resources/views/profile/update-password-form.blade.php b/resources/views/profile/update-password-form.blade.php
new file mode 100644
index 0000000..b536005
--- /dev/null
+++ b/resources/views/profile/update-password-form.blade.php
@@ -0,0 +1,39 @@
+
+
+ {{ __('Update Password') }}
+
+
+
+ {{ __('Ensure your account is using a long, random password to stay secure.') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Saved.') }}
+
+
+
+ {{ __('Save') }}
+
+
+
diff --git a/resources/views/profile/update-profile-information-form.blade.php b/resources/views/profile/update-profile-information-form.blade.php
new file mode 100644
index 0000000..c104ddb
--- /dev/null
+++ b/resources/views/profile/update-profile-information-form.blade.php
@@ -0,0 +1,95 @@
+
+
+ {{ __('Profile Information') }}
+
+
+
+ {{ __('Update your account\'s profile information and email address.') }}
+
+
+
+
+ @if (Laravel\Jetstream\Jetstream::managesProfilePhotos())
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Select A New Photo') }}
+
+
+ @if ($this->user->profile_photo_path)
+
+ {{ __('Remove Photo') }}
+
+ @endif
+
+
+
+ @endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @if (Laravel\Fortify\Features::enabled(Laravel\Fortify\Features::emailVerification()) && ! $this->user->hasVerifiedEmail())
+
+ {{ __('Your email address is unverified.') }}
+
+
+ {{ __('Click here to re-send the verification email.') }}
+
+
+
+ @if ($this->verificationLinkSent)
+
+ {{ __('A new verification link has been sent to your email address.') }}
+
+ @endif
+ @endif
+
+
+
+
+
+ {{ __('Saved.') }}
+
+
+
+ {{ __('Save') }}
+
+
+
diff --git a/resources/views/proyectos/_form.blade.php b/resources/views/proyectos/_form.blade.php
new file mode 100644
index 0000000..d2d83ce
--- /dev/null
+++ b/resources/views/proyectos/_form.blade.php
@@ -0,0 +1,14 @@
+@csrf
+
+
+ Nombre
+
+
+
+
+ Descripcion
+
+
+
+
+ {{ $btnText }}
\ No newline at end of file
diff --git a/resources/views/proyectos/create.blade.php b/resources/views/proyectos/create.blade.php
new file mode 100644
index 0000000..aa9a391
--- /dev/null
+++ b/resources/views/proyectos/create.blade.php
@@ -0,0 +1,17 @@
+@extends('layouts.plantilla')
+
+@section('title','Crear Proyecto')
+
+@section('content')
+
+ Crear nuevo Proyecto
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/proyectos/edit.blade.php b/resources/views/proyectos/edit.blade.php
new file mode 100644
index 0000000..8eb915a
--- /dev/null
+++ b/resources/views/proyectos/edit.blade.php
@@ -0,0 +1,18 @@
+@extends('layouts.plantilla')
+
+@section('title','Editar Proyecto')
+
+@section('content')
+
+ Editar Proyecto
+
+ @include('partials.validation-errors')
+
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/proyectos/index.blade.php b/resources/views/proyectos/index.blade.php
new file mode 100644
index 0000000..c82c451
--- /dev/null
+++ b/resources/views/proyectos/index.blade.php
@@ -0,0 +1,48 @@
+@extends('layouts.plantilla')
+
+@section('title','Proyectos')
+
+@section('content')
+
+ Proyectos
+
+ @auth
+ Crear Proyecto
+ @endauth
+
+ @if(session('status'))
+
+
+ {{ session('status') }}
+
+ @else
+
+ @endif
+
+
+
+
+ ID
+ Nombre
+ Fecha modificación
+ Ver
+
+
+
+ @forelse($proyectos as $item)
+
+ {{$item->id}}
+ {{ $item->nombre }}
+ {{ $item->updated_at->format('d/m/Y') }}
+ VER
+
+ @empty
+
+ No hay Proyectos para mostrar
+
+ @endforelse
+
+
+ {{ $proyectos->links() }}
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/proyectos/show.blade.php b/resources/views/proyectos/show.blade.php
new file mode 100644
index 0000000..aa3fb22
--- /dev/null
+++ b/resources/views/proyectos/show.blade.php
@@ -0,0 +1,52 @@
+@extends('layouts.plantilla')
+
+@section('title', 'Proyecto | '.$proyecto->nombre)
+
+@section('content')
+
+ Consultar Proyecto
+
+
+
+
+
+
+
+ @auth
+
+ @endauth
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/teams/create-team-form.blade.php b/resources/views/teams/create-team-form.blade.php
new file mode 100644
index 0000000..601823c
--- /dev/null
+++ b/resources/views/teams/create-team-form.blade.php
@@ -0,0 +1,36 @@
+
+
+ {{ __('Team Details') }}
+
+
+
+ {{ __('Create a new team to collaborate with others on projects.') }}
+
+
+
+
+
+
+
+
+
+
+
{{ $this->user->name }}
+
{{ $this->user->email }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ __('Create') }}
+
+
+
diff --git a/resources/views/teams/create.blade.php b/resources/views/teams/create.blade.php
new file mode 100644
index 0000000..12d006a
--- /dev/null
+++ b/resources/views/teams/create.blade.php
@@ -0,0 +1,13 @@
+
+
+
+ {{ __('Create Team') }}
+
+
+
+
+
+ @livewire('teams.create-team-form')
+
+
+
diff --git a/resources/views/teams/delete-team-form.blade.php b/resources/views/teams/delete-team-form.blade.php
new file mode 100644
index 0000000..49a2d7d
--- /dev/null
+++ b/resources/views/teams/delete-team-form.blade.php
@@ -0,0 +1,42 @@
+
+
+ {{ __('Delete Team') }}
+
+
+
+ {{ __('Permanently delete this team.') }}
+
+
+
+
+ {{ __('Once a team is deleted, all of its resources and data will be permanently deleted. Before deleting this team, please download any data or information regarding this team that you wish to retain.') }}
+
+
+
+
+ {{ __('Delete Team') }}
+
+
+
+
+
+
+ {{ __('Delete Team') }}
+
+
+
+ {{ __('Are you sure you want to delete this team? Once a team is deleted, all of its resources and data will be permanently deleted.') }}
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Delete Team') }}
+
+
+
+
+
diff --git a/resources/views/teams/show.blade.php b/resources/views/teams/show.blade.php
new file mode 100644
index 0000000..92c4383
--- /dev/null
+++ b/resources/views/teams/show.blade.php
@@ -0,0 +1,23 @@
+
+
+
+ {{ __('Team Settings') }}
+
+
+
+
+
+ @livewire('teams.update-team-name-form', ['team' => $team])
+
+ @livewire('teams.team-member-manager', ['team' => $team])
+
+ @if (Gate::check('delete', $team) && ! $team->personal_team)
+
+
+
+ @livewire('teams.delete-team-form', ['team' => $team])
+
+ @endif
+
+
+
diff --git a/resources/views/teams/team-member-manager.blade.php b/resources/views/teams/team-member-manager.blade.php
new file mode 100644
index 0000000..3594dc6
--- /dev/null
+++ b/resources/views/teams/team-member-manager.blade.php
@@ -0,0 +1,256 @@
+
+ @if (Gate::check('addTeamMember', $team))
+
+
+
+
+
+
+ {{ __('Add Team Member') }}
+
+
+
+ {{ __('Add a new team member to your team, allowing them to collaborate with you.') }}
+
+
+
+
+
+ {{ __('Please provide the email address of the person you would like to add to this team.') }}
+
+
+
+
+
+
+
+
+
+
+
+ @if (count($this->roles) > 0)
+
+
+
+
+
+ @foreach ($this->roles as $index => $role)
+
+
+
+ @endforeach
+
+
+ @endif
+
+
+
+
+ {{ __('Added.') }}
+
+
+
+ {{ __('Add') }}
+
+
+
+
+ @endif
+
+ @if ($team->teamInvitations->isNotEmpty() && Gate::check('addTeamMember', $team))
+
+
+
+
+
+
+ {{ __('Pending Team Invitations') }}
+
+
+
+ {{ __('These people have been invited to your team and have been sent an invitation email. They may join the team by accepting the email invitation.') }}
+
+
+
+
+ @foreach ($team->teamInvitations as $invitation)
+
+
{{ $invitation->email }}
+
+
+ @if (Gate::check('removeTeamMember', $team))
+
+
+ {{ __('Cancel') }}
+
+ @endif
+
+
+ @endforeach
+
+
+
+
+ @endif
+
+ @if ($team->users->isNotEmpty())
+
+
+
+
+
+
+ {{ __('Team Members') }}
+
+
+
+ {{ __('All of the people that are part of this team.') }}
+
+
+
+
+
+ @foreach ($team->users->sortBy('name') as $user)
+
+
+
+
{{ $user->name }}
+
+
+
+
+ @if (Gate::check('addTeamMember', $team) && Laravel\Jetstream\Jetstream::hasRoles())
+
+ {{ Laravel\Jetstream\Jetstream::findRole($user->membership->role)->name }}
+
+ @elseif (Laravel\Jetstream\Jetstream::hasRoles())
+
+ {{ Laravel\Jetstream\Jetstream::findRole($user->membership->role)->name }}
+
+ @endif
+
+
+ @if ($this->user->id === $user->id)
+
+ {{ __('Leave') }}
+
+
+
+ @elseif (Gate::check('removeTeamMember', $team))
+
+ {{ __('Remove') }}
+
+ @endif
+
+
+ @endforeach
+
+
+
+
+ @endif
+
+
+
+
+ {{ __('Manage Role') }}
+
+
+
+
+ @foreach ($this->roles as $index => $role)
+
+
+
+
+
+ {{ $role->name }}
+
+
+ @if ($currentRole == $role->key)
+
+ @endif
+
+
+
+
+ {{ $role->description }}
+
+
+
+ @endforeach
+
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Save') }}
+
+
+
+
+
+
+
+ {{ __('Leave Team') }}
+
+
+
+ {{ __('Are you sure you would like to leave this team?') }}
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Leave') }}
+
+
+
+
+
+
+
+ {{ __('Remove Team Member') }}
+
+
+
+ {{ __('Are you sure you would like to remove this person from the team?') }}
+
+
+
+
+ {{ __('Cancel') }}
+
+
+
+ {{ __('Remove') }}
+
+
+
+
diff --git a/resources/views/teams/update-team-name-form.blade.php b/resources/views/teams/update-team-name-form.blade.php
new file mode 100644
index 0000000..baecd34
--- /dev/null
+++ b/resources/views/teams/update-team-name-form.blade.php
@@ -0,0 +1,50 @@
+
+
+ {{ __('Team Name') }}
+
+
+
+ {{ __('The team\'s name and owner information.') }}
+
+
+
+
+
+
+
+
+
+
+
+
{{ $team->owner->name }}
+
{{ $team->owner->email }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @if (Gate::check('update', $team))
+
+
+ {{ __('Saved.') }}
+
+
+
+ {{ __('Save') }}
+
+
+ @endif
+
diff --git a/resources/views/terms.blade.php b/resources/views/terms.blade.php
new file mode 100644
index 0000000..bb8b193
--- /dev/null
+++ b/resources/views/terms.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ {!! $terms !!}
+
+
+
+
diff --git a/routes/api.php b/routes/api.php
index eb6fa48..a72a532 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -2,6 +2,9 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\Api\CooperanteController;
+use App\Http\Controllers\Api\ProyectoController;
+use App\Http\Controllers\Api\AsignacionController;
/*
|--------------------------------------------------------------------------
@@ -17,3 +20,5 @@
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
+
+Route::apiResource('proyectos',ProyectoController::class);
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index f7452f4..9b890eb 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -2,6 +2,10 @@
use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\CooperanteController;
+use App\Http\Controllers\ProyectoController;
+use App\Http\Controllers\AsignacionController;
+
/*
|--------------------------------------------------------------------------
| Web Routes
@@ -15,4 +19,30 @@
Route::get('/', function () {
return view('inicio');
+})->name('home');
+
+Route::resource('cooperantes', CooperanteController::class);
+
+Route::resource('proyectos', ProyectoController::class);
+
+Route::get('asignaciones/reporte/{cooperante?}',[AsignacionController::class,'index'])->name('asignaciones.reporte');
+
+Route::get('asignaciones/create',[AsignacionController::class,'create'])->name('asignaciones.create');
+
+Route::post('asignaciones',[AsignacionController::class,'store'])->name('asignaciones.store');
+
+Route::get('asignaciones/obtenerReporte/{cooperante?}',[AsignacionController::class,'obtenerReporte'])->name('asignaciones.obtenerReporte');
+
+Route::get('asignaciones/{asignacion}/edit', [AsignacionController::class,'edit'])->name('asignaciones.edit');
+
+Route::patch('asignaciones/{asignacion}', [AsignacionController::class,'update'])->name('asignaciones.update');
+
+Route::middleware([
+ 'auth:sanctum',
+ config('jetstream.auth_session'),
+ 'verified'
+])->group(function () {
+ Route::get('/dashboard', function () {
+ return view('dashboard');
+ })->name('dashboard');
});
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..721525b
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,21 @@
+const defaultTheme = require('tailwindcss/defaultTheme');
+
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
+ './vendor/laravel/jetstream/**/*.blade.php',
+ './storage/framework/views/*.php',
+ './resources/views/**/*.blade.php',
+ ],
+
+ theme: {
+ extend: {
+ fontFamily: {
+ sans: ['Nunito', ...defaultTheme.fontFamily.sans],
+ },
+ },
+ },
+
+ plugins: [require('@tailwindcss/forms'), require('@tailwindcss/typography')],
+};
diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php
new file mode 100644
index 0000000..547152f
--- /dev/null
+++ b/tests/CreatesApplication.php
@@ -0,0 +1,22 @@
+make(Kernel::class)->bootstrap();
+
+ return $app;
+ }
+}
diff --git a/tests/Feature/ApiTokenPermissionsTest.php b/tests/Feature/ApiTokenPermissionsTest.php
new file mode 100644
index 0000000..5fbd909
--- /dev/null
+++ b/tests/Feature/ApiTokenPermissionsTest.php
@@ -0,0 +1,45 @@
+markTestSkipped('API support is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $token = $user->tokens()->create([
+ 'name' => 'Test Token',
+ 'token' => Str::random(40),
+ 'abilities' => ['create', 'read'],
+ ]);
+
+ Livewire::test(ApiTokenManager::class)
+ ->set(['managingPermissionsFor' => $token])
+ ->set(['updateApiTokenForm' => [
+ 'permissions' => [
+ 'delete',
+ 'missing-permission',
+ ],
+ ]])
+ ->call('updateApiToken');
+
+ $this->assertTrue($user->fresh()->tokens->first()->can('delete'));
+ $this->assertFalse($user->fresh()->tokens->first()->can('read'));
+ $this->assertFalse($user->fresh()->tokens->first()->can('missing-permission'));
+ }
+}
diff --git a/tests/Feature/AuthenticationTest.php b/tests/Feature/AuthenticationTest.php
new file mode 100644
index 0000000..2dbceac
--- /dev/null
+++ b/tests/Feature/AuthenticationTest.php
@@ -0,0 +1,45 @@
+get('/login');
+
+ $response->assertStatus(200);
+ }
+
+ public function test_users_can_authenticate_using_the_login_screen()
+ {
+ $user = User::factory()->create();
+
+ $response = $this->post('/login', [
+ 'email' => $user->email,
+ 'password' => 'password',
+ ]);
+
+ $this->assertAuthenticated();
+ $response->assertRedirect(RouteServiceProvider::HOME);
+ }
+
+ public function test_users_can_not_authenticate_with_invalid_password()
+ {
+ $user = User::factory()->create();
+
+ $this->post('/login', [
+ 'email' => $user->email,
+ 'password' => 'wrong-password',
+ ]);
+
+ $this->assertGuest();
+ }
+}
diff --git a/tests/Feature/BrowserSessionsTest.php b/tests/Feature/BrowserSessionsTest.php
new file mode 100644
index 0000000..bac0e93
--- /dev/null
+++ b/tests/Feature/BrowserSessionsTest.php
@@ -0,0 +1,24 @@
+actingAs($user = User::factory()->create());
+
+ Livewire::test(LogoutOtherBrowserSessionsForm::class)
+ ->set('password', 'password')
+ ->call('logoutOtherBrowserSessions')
+ ->assertSuccessful();
+ }
+}
diff --git a/tests/Feature/CreateApiTokenTest.php b/tests/Feature/CreateApiTokenTest.php
new file mode 100644
index 0000000..465ea38
--- /dev/null
+++ b/tests/Feature/CreateApiTokenTest.php
@@ -0,0 +1,39 @@
+markTestSkipped('API support is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ Livewire::test(ApiTokenManager::class)
+ ->set(['createApiTokenForm' => [
+ 'name' => 'Test Token',
+ 'permissions' => [
+ 'read',
+ 'update',
+ ],
+ ]])
+ ->call('createApiToken');
+
+ $this->assertCount(1, $user->fresh()->tokens);
+ $this->assertEquals('Test Token', $user->fresh()->tokens->first()->name);
+ $this->assertTrue($user->fresh()->tokens->first()->can('read'));
+ $this->assertFalse($user->fresh()->tokens->first()->can('delete'));
+ }
+}
diff --git a/tests/Feature/CreateTeamTest.php b/tests/Feature/CreateTeamTest.php
new file mode 100644
index 0000000..b39a793
--- /dev/null
+++ b/tests/Feature/CreateTeamTest.php
@@ -0,0 +1,26 @@
+actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ Livewire::test(CreateTeamForm::class)
+ ->set(['state' => ['name' => 'Test Team']])
+ ->call('createTeam');
+
+ $this->assertCount(2, $user->fresh()->ownedTeams);
+ $this->assertEquals('Test Team', $user->fresh()->ownedTeams()->latest('id')->first()->name);
+ }
+}
diff --git a/tests/Feature/DeleteAccountTest.php b/tests/Feature/DeleteAccountTest.php
new file mode 100644
index 0000000..7267957
--- /dev/null
+++ b/tests/Feature/DeleteAccountTest.php
@@ -0,0 +1,46 @@
+markTestSkipped('Account deletion is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->create());
+
+ $component = Livewire::test(DeleteUserForm::class)
+ ->set('password', 'password')
+ ->call('deleteUser');
+
+ $this->assertNull($user->fresh());
+ }
+
+ public function test_correct_password_must_be_provided_before_account_can_be_deleted()
+ {
+ if (! Features::hasAccountDeletionFeatures()) {
+ return $this->markTestSkipped('Account deletion is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->create());
+
+ Livewire::test(DeleteUserForm::class)
+ ->set('password', 'wrong-password')
+ ->call('deleteUser')
+ ->assertHasErrors(['password']);
+
+ $this->assertNotNull($user->fresh());
+ }
+}
diff --git a/tests/Feature/DeleteApiTokenTest.php b/tests/Feature/DeleteApiTokenTest.php
new file mode 100644
index 0000000..9128862
--- /dev/null
+++ b/tests/Feature/DeleteApiTokenTest.php
@@ -0,0 +1,37 @@
+markTestSkipped('API support is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $token = $user->tokens()->create([
+ 'name' => 'Test Token',
+ 'token' => Str::random(40),
+ 'abilities' => ['create', 'read'],
+ ]);
+
+ Livewire::test(ApiTokenManager::class)
+ ->set(['apiTokenIdBeingDeleted' => $token->id])
+ ->call('deleteApiToken');
+
+ $this->assertCount(0, $user->fresh()->tokens);
+ }
+}
diff --git a/tests/Feature/DeleteTeamTest.php b/tests/Feature/DeleteTeamTest.php
new file mode 100644
index 0000000..92541a9
--- /dev/null
+++ b/tests/Feature/DeleteTeamTest.php
@@ -0,0 +1,45 @@
+actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $user->ownedTeams()->save($team = Team::factory()->make([
+ 'personal_team' => false,
+ ]));
+
+ $team->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'test-role']
+ );
+
+ $component = Livewire::test(DeleteTeamForm::class, ['team' => $team->fresh()])
+ ->call('deleteTeam');
+
+ $this->assertNull($team->fresh());
+ $this->assertCount(0, $otherUser->fresh()->teams);
+ }
+
+ public function test_personal_teams_cant_be_deleted()
+ {
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $component = Livewire::test(DeleteTeamForm::class, ['team' => $user->currentTeam])
+ ->call('deleteTeam')
+ ->assertHasErrors(['team']);
+
+ $this->assertNotNull($user->currentTeam->fresh());
+ }
+}
diff --git a/tests/Feature/EmailVerificationTest.php b/tests/Feature/EmailVerificationTest.php
new file mode 100644
index 0000000..f240e12
--- /dev/null
+++ b/tests/Feature/EmailVerificationTest.php
@@ -0,0 +1,73 @@
+markTestSkipped('Email verification not enabled.');
+ }
+
+ $user = User::factory()->withPersonalTeam()->unverified()->create();
+
+ $response = $this->actingAs($user)->get('/email/verify');
+
+ $response->assertStatus(200);
+ }
+
+ public function test_email_can_be_verified()
+ {
+ if (! Features::enabled(Features::emailVerification())) {
+ return $this->markTestSkipped('Email verification not enabled.');
+ }
+
+ Event::fake();
+
+ $user = User::factory()->unverified()->create();
+
+ $verificationUrl = URL::temporarySignedRoute(
+ 'verification.verify',
+ now()->addMinutes(60),
+ ['id' => $user->id, 'hash' => sha1($user->email)]
+ );
+
+ $response = $this->actingAs($user)->get($verificationUrl);
+
+ Event::assertDispatched(Verified::class);
+
+ $this->assertTrue($user->fresh()->hasVerifiedEmail());
+ $response->assertRedirect(RouteServiceProvider::HOME.'?verified=1');
+ }
+
+ public function test_email_can_not_verified_with_invalid_hash()
+ {
+ if (! Features::enabled(Features::emailVerification())) {
+ return $this->markTestSkipped('Email verification not enabled.');
+ }
+
+ $user = User::factory()->unverified()->create();
+
+ $verificationUrl = URL::temporarySignedRoute(
+ 'verification.verify',
+ now()->addMinutes(60),
+ ['id' => $user->id, 'hash' => sha1('wrong-email')]
+ );
+
+ $this->actingAs($user)->get($verificationUrl);
+
+ $this->assertFalse($user->fresh()->hasVerifiedEmail());
+ }
+}
diff --git a/tests/Feature/InviteTeamMemberTest.php b/tests/Feature/InviteTeamMemberTest.php
new file mode 100644
index 0000000..dd2d7ed
--- /dev/null
+++ b/tests/Feature/InviteTeamMemberTest.php
@@ -0,0 +1,63 @@
+markTestSkipped('Team invitations not enabled.');
+ }
+
+ Mail::fake();
+
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('addTeamMemberForm', [
+ 'email' => 'test@example.com',
+ 'role' => 'admin',
+ ])->call('addTeamMember');
+
+ Mail::assertSent(TeamInvitation::class);
+
+ $this->assertCount(1, $user->currentTeam->fresh()->teamInvitations);
+ }
+
+ public function test_team_member_invitations_can_be_cancelled()
+ {
+ if (! Features::sendsTeamInvitations()) {
+ return $this->markTestSkipped('Team invitations not enabled.');
+ }
+
+ Mail::fake();
+
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ // Add the team member...
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('addTeamMemberForm', [
+ 'email' => 'test@example.com',
+ 'role' => 'admin',
+ ])->call('addTeamMember');
+
+ $invitationId = $user->currentTeam->fresh()->teamInvitations->first()->id;
+
+ // Cancel the team invitation...
+ $component->call('cancelTeamInvitation', $invitationId);
+
+ $this->assertCount(0, $user->currentTeam->fresh()->teamInvitations);
+ }
+}
diff --git a/tests/Feature/LeaveTeamTest.php b/tests/Feature/LeaveTeamTest.php
new file mode 100644
index 0000000..e3232e2
--- /dev/null
+++ b/tests/Feature/LeaveTeamTest.php
@@ -0,0 +1,41 @@
+withPersonalTeam()->create();
+
+ $user->currentTeam->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'admin']
+ );
+
+ $this->actingAs($otherUser);
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->call('leaveTeam');
+
+ $this->assertCount(0, $user->currentTeam->fresh()->users);
+ }
+
+ public function test_team_owners_cant_leave_their_own_team()
+ {
+ $this->actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->call('leaveTeam')
+ ->assertHasErrors(['team']);
+
+ $this->assertNotNull($user->currentTeam->fresh());
+ }
+}
diff --git a/tests/Feature/PasswordConfirmationTest.php b/tests/Feature/PasswordConfirmationTest.php
new file mode 100644
index 0000000..a31fbab
--- /dev/null
+++ b/tests/Feature/PasswordConfirmationTest.php
@@ -0,0 +1,45 @@
+withPersonalTeam()->create();
+
+ $response = $this->actingAs($user)->get('/user/confirm-password');
+
+ $response->assertStatus(200);
+ }
+
+ public function test_password_can_be_confirmed()
+ {
+ $user = User::factory()->create();
+
+ $response = $this->actingAs($user)->post('/user/confirm-password', [
+ 'password' => 'password',
+ ]);
+
+ $response->assertRedirect();
+ $response->assertSessionHasNoErrors();
+ }
+
+ public function test_password_is_not_confirmed_with_invalid_password()
+ {
+ $user = User::factory()->create();
+
+ $response = $this->actingAs($user)->post('/user/confirm-password', [
+ 'password' => 'wrong-password',
+ ]);
+
+ $response->assertSessionHasErrors();
+ }
+}
diff --git a/tests/Feature/PasswordResetTest.php b/tests/Feature/PasswordResetTest.php
new file mode 100644
index 0000000..13b94b2
--- /dev/null
+++ b/tests/Feature/PasswordResetTest.php
@@ -0,0 +1,94 @@
+markTestSkipped('Password updates are not enabled.');
+ }
+
+ $response = $this->get('/forgot-password');
+
+ $response->assertStatus(200);
+ }
+
+ public function test_reset_password_link_can_be_requested()
+ {
+ if (! Features::enabled(Features::resetPasswords())) {
+ return $this->markTestSkipped('Password updates are not enabled.');
+ }
+
+ Notification::fake();
+
+ $user = User::factory()->create();
+
+ $response = $this->post('/forgot-password', [
+ 'email' => $user->email,
+ ]);
+
+ Notification::assertSentTo($user, ResetPassword::class);
+ }
+
+ public function test_reset_password_screen_can_be_rendered()
+ {
+ if (! Features::enabled(Features::resetPasswords())) {
+ return $this->markTestSkipped('Password updates are not enabled.');
+ }
+
+ Notification::fake();
+
+ $user = User::factory()->create();
+
+ $response = $this->post('/forgot-password', [
+ 'email' => $user->email,
+ ]);
+
+ Notification::assertSentTo($user, ResetPassword::class, function ($notification) {
+ $response = $this->get('/reset-password/'.$notification->token);
+
+ $response->assertStatus(200);
+
+ return true;
+ });
+ }
+
+ public function test_password_can_be_reset_with_valid_token()
+ {
+ if (! Features::enabled(Features::resetPasswords())) {
+ return $this->markTestSkipped('Password updates are not enabled.');
+ }
+
+ Notification::fake();
+
+ $user = User::factory()->create();
+
+ $response = $this->post('/forgot-password', [
+ 'email' => $user->email,
+ ]);
+
+ Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) {
+ $response = $this->post('/reset-password', [
+ 'token' => $notification->token,
+ 'email' => $user->email,
+ 'password' => 'password',
+ 'password_confirmation' => 'password',
+ ]);
+
+ $response->assertSessionHasNoErrors();
+
+ return true;
+ });
+ }
+}
diff --git a/tests/Feature/ProfileInformationTest.php b/tests/Feature/ProfileInformationTest.php
new file mode 100644
index 0000000..5487825
--- /dev/null
+++ b/tests/Feature/ProfileInformationTest.php
@@ -0,0 +1,36 @@
+actingAs($user = User::factory()->create());
+
+ $component = Livewire::test(UpdateProfileInformationForm::class);
+
+ $this->assertEquals($user->name, $component->state['name']);
+ $this->assertEquals($user->email, $component->state['email']);
+ }
+
+ public function test_profile_information_can_be_updated()
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ Livewire::test(UpdateProfileInformationForm::class)
+ ->set('state', ['name' => 'Test Name', 'email' => 'test@example.com'])
+ ->call('updateProfileInformation');
+
+ $this->assertEquals('Test Name', $user->fresh()->name);
+ $this->assertEquals('test@example.com', $user->fresh()->email);
+ }
+}
diff --git a/tests/Feature/ProyectoTest.php b/tests/Feature/ProyectoTest.php
new file mode 100644
index 0000000..e768c04
--- /dev/null
+++ b/tests/Feature/ProyectoTest.php
@@ -0,0 +1,128 @@
+get('/proyectos');
+ $response->assertStatus(200);
+ //$response->ddHeaders();
+ //$response->ddSession();
+ //$response->dd();
+ //$this->assertTrue(true);
+
+ $proyectos=Proyecto::latest('updated_at')->paginate();
+ $response->assertViewIs('proyectos.index');
+ $response->assertViewHas('proyectos',$proyectos);
+ }
+
+ public function test_example_show(){
+ $proyecto=Proyecto::first();
+
+ $response = $this->get('/proyectos/'.$proyecto->id);
+
+ $response->assertStatus(200);
+
+ $this->assertEquals('Garth Romaguera III',$proyecto->nombre);
+
+ }
+
+ public function test_example_create()
+ {
+ $response = $this->get('/proyectos/create');
+ $response->assertStatus(200);
+ $response->assertViewIs('proyectos.create');
+ }
+
+ public function test_example_store()
+ {
+ $this->withoutExceptionHandling();
+ $proyecto = [
+ 'nombre' => Str::random(20),
+ 'descripcion' => "TEST",
+ ];
+
+ $response = $this->post('/proyectos', $proyecto);
+ $response->assertRedirect('/proyectos');
+ //$this->assertCount(1,Proyecto::all());
+
+ //var_dump($proyecto['nombre']);
+ $proyectoDB=Proyecto::where("nombre","=", $proyecto['nombre'])->get();
+ //var_dump($proyectoDB->count());
+ //$this->assertEquals($proyecto['nombre'],$proyectoDB->nombre);
+ $this->assertTrue($proyectoDB->count()>0);
+
+ // $response->assertStatus(200);
+ //$response = $this->call('POST', '/proyectos', $test_post);
+ //$response = $this->actingAs($user)->post('/admin/posts', $test_post);
+ //$response->assertStatus(200);
+
+ //$this->assertTrue(true);
+
+ }
+
+ public function test_example_update(){
+ $proyecto= Proyecto::factory()->create();
+
+ //$proyecto= Proyecto::factory()->create(['descripcion' => "TEST"]);
+
+ $proyectoModificado = [
+ 'nombre' => "MODIFICADO6",
+ 'descripcion' => "TEST",
+ ];
+
+ if($proyecto){
+ $response=$this->put('/proyectos/'.$proyecto->id,$proyectoModificado);
+ $response->assertRedirect('/proyectos?'.$proyecto->id);
+ }
+
+ $proyecto = $proyecto->fresh();
+
+ $this->assertEquals('MODIFICADO6',$proyecto->nombre);
+
+ $this->assertTrue(true);
+ }
+
+ public function test_example_delete()
+ {
+ $proyecto= Proyecto::factory()->create();
+
+ //$proyecto= Proyecto::first();
+
+ if($proyecto){
+ $response = $this->delete('/proyectos/'.$proyecto->id);
+ $response->assertRedirect('/proyectos');
+ }
+
+ }
+
+ public function test_proyecto_nombre_es_requerido(){
+
+ //$this->withoutExceptionHandling();
+
+ $proyecto = [
+ 'nombre' => '',
+ 'descripcion' => "TEST",
+ ];
+
+ $response = $this->post('/proyectos', $proyecto);
+
+ $response->assertSessionHasErrors(['nombre']);
+ }
+}
diff --git a/tests/Feature/RegistrationTest.php b/tests/Feature/RegistrationTest.php
new file mode 100644
index 0000000..aae144f
--- /dev/null
+++ b/tests/Feature/RegistrationTest.php
@@ -0,0 +1,54 @@
+markTestSkipped('Registration support is not enabled.');
+ }
+
+ $response = $this->get('/register');
+
+ $response->assertStatus(200);
+ }
+
+ public function test_registration_screen_cannot_be_rendered_if_support_is_disabled()
+ {
+ if (Features::enabled(Features::registration())) {
+ return $this->markTestSkipped('Registration support is enabled.');
+ }
+
+ $response = $this->get('/register');
+
+ $response->assertStatus(404);
+ }
+
+ public function test_new_users_can_register()
+ {
+ if (! Features::enabled(Features::registration())) {
+ return $this->markTestSkipped('Registration support is not enabled.');
+ }
+
+ $response = $this->post('/register', [
+ 'name' => 'Test User',
+ 'email' => 'test@example.com',
+ 'password' => 'password',
+ 'password_confirmation' => 'password',
+ 'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature(),
+ ]);
+
+ $this->assertAuthenticated();
+ $response->assertRedirect(RouteServiceProvider::HOME);
+ }
+}
diff --git a/tests/Feature/RemoveTeamMemberTest.php b/tests/Feature/RemoveTeamMemberTest.php
new file mode 100644
index 0000000..b9bab59
--- /dev/null
+++ b/tests/Feature/RemoveTeamMemberTest.php
@@ -0,0 +1,45 @@
+actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $user->currentTeam->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'admin']
+ );
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('teamMemberIdBeingRemoved', $otherUser->id)
+ ->call('removeTeamMember');
+
+ $this->assertCount(0, $user->currentTeam->fresh()->users);
+ }
+
+ public function test_only_team_owner_can_remove_team_members()
+ {
+ $user = User::factory()->withPersonalTeam()->create();
+
+ $user->currentTeam->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'admin']
+ );
+
+ $this->actingAs($otherUser);
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('teamMemberIdBeingRemoved', $user->id)
+ ->call('removeTeamMember')
+ ->assertStatus(403);
+ }
+}
diff --git a/tests/Feature/TwoFactorAuthenticationSettingsTest.php b/tests/Feature/TwoFactorAuthenticationSettingsTest.php
new file mode 100644
index 0000000..fa2ddd5
--- /dev/null
+++ b/tests/Feature/TwoFactorAuthenticationSettingsTest.php
@@ -0,0 +1,76 @@
+markTestSkipped('Two factor authentication is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->create());
+
+ $this->withSession(['auth.password_confirmed_at' => time()]);
+
+ Livewire::test(TwoFactorAuthenticationForm::class)
+ ->call('enableTwoFactorAuthentication');
+
+ $user = $user->fresh();
+
+ $this->assertNotNull($user->two_factor_secret);
+ $this->assertCount(8, $user->recoveryCodes());
+ }
+
+ public function test_recovery_codes_can_be_regenerated()
+ {
+ if (! Features::canManageTwoFactorAuthentication()) {
+ return $this->markTestSkipped('Two factor authentication is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->create());
+
+ $this->withSession(['auth.password_confirmed_at' => time()]);
+
+ $component = Livewire::test(TwoFactorAuthenticationForm::class)
+ ->call('enableTwoFactorAuthentication')
+ ->call('regenerateRecoveryCodes');
+
+ $user = $user->fresh();
+
+ $component->call('regenerateRecoveryCodes');
+
+ $this->assertCount(8, $user->recoveryCodes());
+ $this->assertCount(8, array_diff($user->recoveryCodes(), $user->fresh()->recoveryCodes()));
+ }
+
+ public function test_two_factor_authentication_can_be_disabled()
+ {
+ if (! Features::canManageTwoFactorAuthentication()) {
+ return $this->markTestSkipped('Two factor authentication is not enabled.');
+ }
+
+ $this->actingAs($user = User::factory()->create());
+
+ $this->withSession(['auth.password_confirmed_at' => time()]);
+
+ $component = Livewire::test(TwoFactorAuthenticationForm::class)
+ ->call('enableTwoFactorAuthentication');
+
+ $this->assertNotNull($user->fresh()->two_factor_secret);
+
+ $component->call('disableTwoFactorAuthentication');
+
+ $this->assertNull($user->fresh()->two_factor_secret);
+ }
+}
diff --git a/tests/Feature/UpdatePasswordTest.php b/tests/Feature/UpdatePasswordTest.php
new file mode 100644
index 0000000..a4588c0
--- /dev/null
+++ b/tests/Feature/UpdatePasswordTest.php
@@ -0,0 +1,62 @@
+actingAs($user = User::factory()->create());
+
+ Livewire::test(UpdatePasswordForm::class)
+ ->set('state', [
+ 'current_password' => 'password',
+ 'password' => 'new-password',
+ 'password_confirmation' => 'new-password',
+ ])
+ ->call('updatePassword');
+
+ $this->assertTrue(Hash::check('new-password', $user->fresh()->password));
+ }
+
+ public function test_current_password_must_be_correct()
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ Livewire::test(UpdatePasswordForm::class)
+ ->set('state', [
+ 'current_password' => 'wrong-password',
+ 'password' => 'new-password',
+ 'password_confirmation' => 'new-password',
+ ])
+ ->call('updatePassword')
+ ->assertHasErrors(['current_password']);
+
+ $this->assertTrue(Hash::check('password', $user->fresh()->password));
+ }
+
+ public function test_new_passwords_must_match()
+ {
+ $this->actingAs($user = User::factory()->create());
+
+ Livewire::test(UpdatePasswordForm::class)
+ ->set('state', [
+ 'current_password' => 'password',
+ 'password' => 'new-password',
+ 'password_confirmation' => 'wrong-password',
+ ])
+ ->call('updatePassword')
+ ->assertHasErrors(['password']);
+
+ $this->assertTrue(Hash::check('password', $user->fresh()->password));
+ }
+}
diff --git a/tests/Feature/UpdateTeamMemberRoleTest.php b/tests/Feature/UpdateTeamMemberRoleTest.php
new file mode 100644
index 0000000..b7a0d87
--- /dev/null
+++ b/tests/Feature/UpdateTeamMemberRoleTest.php
@@ -0,0 +1,53 @@
+actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ $user->currentTeam->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'admin']
+ );
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('managingRoleFor', $otherUser)
+ ->set('currentRole', 'editor')
+ ->call('updateRole');
+
+ $this->assertTrue($otherUser->fresh()->hasTeamRole(
+ $user->currentTeam->fresh(), 'editor'
+ ));
+ }
+
+ public function test_only_team_owner_can_update_team_member_roles()
+ {
+ $user = User::factory()->withPersonalTeam()->create();
+
+ $user->currentTeam->users()->attach(
+ $otherUser = User::factory()->create(), ['role' => 'admin']
+ );
+
+ $this->actingAs($otherUser);
+
+ $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
+ ->set('managingRoleFor', $otherUser)
+ ->set('currentRole', 'editor')
+ ->call('updateRole')
+ ->assertStatus(403);
+
+ $this->assertTrue($otherUser->fresh()->hasTeamRole(
+ $user->currentTeam->fresh(), 'admin'
+ ));
+ }
+}
diff --git a/tests/Feature/UpdateTeamNameTest.php b/tests/Feature/UpdateTeamNameTest.php
new file mode 100644
index 0000000..f81c92a
--- /dev/null
+++ b/tests/Feature/UpdateTeamNameTest.php
@@ -0,0 +1,26 @@
+actingAs($user = User::factory()->withPersonalTeam()->create());
+
+ Livewire::test(UpdateTeamNameForm::class, ['team' => $user->currentTeam])
+ ->set(['state' => ['name' => 'Test Team']])
+ ->call('updateTeamName');
+
+ $this->assertCount(1, $user->fresh()->ownedTeams);
+ $this->assertEquals('Test Team', $user->currentTeam->fresh()->name);
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
new file mode 100644
index 0000000..2932d4a
--- /dev/null
+++ b/tests/TestCase.php
@@ -0,0 +1,10 @@
+