getch 0.0.8 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +44 -0
  5. data/README.md +57 -8
  6. data/bin/setup.sh +4 -2
  7. data/lib/getch.rb +43 -15
  8. data/lib/getch/command.rb +26 -5
  9. data/lib/getch/config.rb +58 -0
  10. data/lib/getch/filesystem.rb +6 -0
  11. data/lib/getch/filesystem/clean.rb +51 -0
  12. data/lib/getch/filesystem/device.rb +61 -0
  13. data/lib/getch/filesystem/ext4.rb +1 -0
  14. data/lib/getch/filesystem/ext4/config.rb +8 -9
  15. data/lib/getch/filesystem/ext4/device.rb +2 -7
  16. data/lib/getch/filesystem/ext4/encrypt/config.rb +69 -47
  17. data/lib/getch/filesystem/ext4/encrypt/deps.rb +21 -15
  18. data/lib/getch/filesystem/ext4/encrypt/device.rb +5 -9
  19. data/lib/getch/filesystem/ext4/encrypt/format.rb +10 -6
  20. data/lib/getch/filesystem/ext4/encrypt/mount.rb +6 -43
  21. data/lib/getch/filesystem/ext4/encrypt/partition.rb +57 -55
  22. data/lib/getch/filesystem/ext4/format.rb +3 -5
  23. data/lib/getch/filesystem/ext4/mount.rb +7 -46
  24. data/lib/getch/filesystem/ext4/partition.rb +16 -39
  25. data/lib/getch/filesystem/lvm.rb +1 -0
  26. data/lib/getch/filesystem/lvm/config.rb +12 -15
  27. data/lib/getch/filesystem/lvm/deps.rb +5 -20
  28. data/lib/getch/filesystem/lvm/device.rb +33 -9
  29. data/lib/getch/filesystem/lvm/encrypt.rb +15 -0
  30. data/lib/getch/filesystem/lvm/encrypt/config.rb +71 -0
  31. data/lib/getch/filesystem/lvm/encrypt/deps.rb +46 -0
  32. data/lib/getch/filesystem/lvm/encrypt/device.rb +46 -0
  33. data/lib/getch/filesystem/lvm/encrypt/format.rb +32 -0
  34. data/lib/getch/filesystem/lvm/encrypt/mount.rb +25 -0
  35. data/lib/getch/filesystem/lvm/encrypt/partition.rb +80 -0
  36. data/lib/getch/filesystem/lvm/format.rb +11 -7
  37. data/lib/getch/filesystem/lvm/mount.rb +7 -46
  38. data/lib/getch/filesystem/lvm/partition.rb +19 -31
  39. data/lib/getch/filesystem/mount.rb +56 -0
  40. data/lib/getch/filesystem/partition.rb +77 -0
  41. data/lib/getch/filesystem/zfs.rb +14 -0
  42. data/lib/getch/filesystem/zfs/config.rb +57 -0
  43. data/lib/getch/filesystem/zfs/deps.rb +95 -0
  44. data/lib/getch/filesystem/zfs/device.rb +58 -0
  45. data/lib/getch/filesystem/zfs/encrypt.rb +15 -0
  46. data/lib/getch/filesystem/zfs/encrypt/config.rb +67 -0
  47. data/lib/getch/filesystem/zfs/encrypt/deps.rb +97 -0
  48. data/lib/getch/filesystem/zfs/encrypt/device.rb +60 -0
  49. data/lib/getch/filesystem/zfs/encrypt/format.rb +105 -0
  50. data/lib/getch/filesystem/zfs/encrypt/mount.rb +51 -0
  51. data/lib/getch/filesystem/zfs/encrypt/partition.rb +65 -0
  52. data/lib/getch/filesystem/zfs/format.rb +114 -0
  53. data/lib/getch/filesystem/zfs/mount.rb +48 -0
  54. data/lib/getch/filesystem/zfs/partition.rb +64 -0
  55. data/lib/getch/gentoo.rb +8 -4
  56. data/lib/getch/gentoo/boot.rb +32 -17
  57. data/lib/getch/gentoo/chroot.rb +12 -26
  58. data/lib/getch/gentoo/config.rb +37 -12
  59. data/lib/getch/gentoo/sources.rb +26 -29
  60. data/lib/getch/gentoo/use.rb +43 -0
  61. data/lib/getch/gentoo/use_flag.rb +64 -0
  62. data/lib/getch/helpers.rb +35 -13
  63. data/lib/getch/options.rb +23 -8
  64. data/lib/getch/version.rb +1 -1
  65. metadata +46 -18
  66. metadata.gz.sig +0 -0
@@ -4,18 +4,16 @@ module Getch
4
4
  class Format < Getch::FileSystem::Ext4::Device
5
5
  def initialize
6
6
  super
7
- @fs = 'ext4'
8
7
  @state = Getch::States.new()
9
8
  format
10
9
  end
11
10
 
12
11
  def format
13
12
  return if STATES[:format]
14
- puts "Format #{@disk} with #{@fs}"
15
- exec("mkfs.fat -F32 #{@dev_boot_efi}") if Helpers::efi?
13
+ exec("mkfs.fat -F32 #{@dev_esp}") if @dev_esp
16
14
  exec("mkswap -f #{@dev_swap}")
17
- exec("mkfs.#{@fs} -F #{@dev_root}")
18
- exec("mkfs.#{@fs} -F #{@dev_home}") if @dev_home
15
+ exec("mkfs.ext4 -F #{@dev_root}")
16
+ exec("mkfs.ext4 -F #{@dev_home}") if @dev_home
19
17
  @state.format
20
18
  end
21
19
 
@@ -1,59 +1,20 @@
1
- require 'fileutils'
2
-
3
1
  module Getch
4
2
  module FileSystem
5
3
  module Ext4
6
4
  class Mount < Getch::FileSystem::Ext4::Device
7
5
  def initialize
8
6
  super
9
- @root_dir = MOUNTPOINT
10
- @boot_dir = "#{@root_dir}/boot"
11
- @boot_efi_dir = "#{@root_dir}/boot/efi"
12
- @home_dir = @user ? "#{@root_dir}/home/#{@user}" : nil
13
- @state = Getch::States.new()
7
+ @mount = Getch::FileSystem::Mount.new
8
+ @state = Getch::States.new
14
9
  end
15
10
 
16
11
  def run
17
12
  return if STATES[:mount]
18
- mount_swap
19
- mount_root
20
- mount_boot
21
- mount_home
22
- mount_boot_efi
23
- @state.mount
24
- end
25
-
26
- private
27
-
28
- def mount_swap
29
- return if ! @dev_swap
30
- system("swapon #{@dev_swap}")
31
- end
32
-
33
- def mount_root
34
- return if ! @dev_root
35
- Dir.mkdir(@root_dir, 0700) if ! Dir.exist?(@root_dir)
36
- system("mount #{@dev_root} #{@root_dir}")
37
- end
38
-
39
- def mount_boot_efi
40
- return if ! @dev_boot_efi
41
- FileUtils.mkdir_p @boot_efi_dir, mode: 0700 if ! Dir.exist?(@boot_efi_dir)
42
- system("mount #{@dev_boot_efi} #{@boot_efi_dir}")
43
- end
44
-
45
- def mount_boot
46
- return if ! @dev_boot
47
- FileUtils.mkdir_p @boot_dir, mode: 0700 if ! Dir.exist?(@boot_dir)
48
- system("mount #{@dev_boot} #{@boot_dir}")
49
- end
50
-
51
- def mount_home
52
- return if ! @dev_home
53
- if @user != nil then
54
- FileUtils.mkdir_p @home_dir, mode: 0700 if ! Dir.exist?(@home_dir)
55
- system("mount #{@dev_home} #{@home_dir}")
56
- end
13
+ @mount.swap(@dev_swap)
14
+ @mount.root(@dev_root)
15
+ @mount.boot(@dev_boot)
16
+ @mount.esp(@dev_esp)
17
+ @mount.home(@dev_home)
57
18
  @state.mount
58
19
  end
59
20
  end
@@ -5,13 +5,15 @@ module Getch
5
5
  def initialize
6
6
  super
7
7
  @state = Getch::States.new()
8
+ @clean = Getch::FileSystem::Clean
9
+ @partition = Getch::FileSystem::Partition.new
8
10
  run_partition
9
11
  end
10
12
 
11
13
  def run_partition
12
14
  return if STATES[:partition ]
13
- clear_struct
14
- cleaning
15
+ @clean.struct(@disk, @cache_disk, @home_disk)
16
+ @clean.hdd(@disk, @cache_disk, @home_disk)
15
17
  if Helpers::efi?
16
18
  partition_efi
17
19
  else
@@ -22,35 +24,16 @@ module Getch
22
24
 
23
25
  private
24
26
 
25
- def clear_struct
26
- exec("sgdisk -Z /dev/#{@disk}")
27
- exec("wipefs -a /dev/#{@disk}")
28
- end
29
-
30
- def cleaning
31
- puts
32
- print "Cleaning data on #{@disk}, can be long, avoid this on Flash Memory (SSD,USB,...) ? (n,y) "
33
- case gets.chomp
34
- when /^y|^Y/
35
- bloc=`blockdev --getbsz /dev/#{@disk}`.chomp
36
- exec("dd if=/dev/urandom of=/dev/#{@disk} bs=#{bloc} status=progress")
37
- else
38
- return
39
- end
40
- end
41
-
42
27
  # Follow https://wiki.archlinux.org/index.php/Partitioning
43
28
  def partition_efi
44
- # /boot/efi - EFI system partition - 260MB
45
- # / - Root
46
- # swap - Linux Swap - size of the ram
47
- # /home - Home
48
- mem=`awk '/MemTotal/ {print $2}' /proc/meminfo`.chomp + 'K'
49
-
50
- exec("sgdisk -n1:1M:+260M -t1:EF00 /dev/#{@disk}")
51
- exec("sgdisk -n2:0:+15G -t2:8304 /dev/#{@disk}")
52
- exec("sgdisk -n3:0:+#{mem} -t3:8200 /dev/#{@disk}")
53
- exec("sgdisk -n4:0:0 -t4:8302 /dev/#{@disk}") if @dev_home
29
+ # /efi - EFI system partition - 260MB
30
+ # swap - Linux Swap - size of the ram
31
+ # / - Root
32
+ # /home - Home
33
+ @partition.efi(@dev_esp)
34
+ @partition.swap(@dev_swap)
35
+ @partition.root(@dev_root, "8304")
36
+ @partition.home(@dev_home, "8302") if @dev_home
54
37
  end
55
38
 
56
39
  def partition_bios
@@ -58,16 +41,10 @@ module Getch
58
41
  # / - Root
59
42
  # swap - Linux Swap - size of the ram
60
43
  # /home - Home
61
- mem=`awk '/MemTotal/ {print $2}' /proc/meminfo`.chomp + 'K'
62
-
63
- exec("sgdisk -n1:1MiB:+1MiB -t1:EF02 /dev/#{@disk}")
64
- exec("sgdisk -n2:0:+15G -t2:8304 /dev/#{@disk}")
65
- exec("sgdisk -n3:0:+#{mem} -t3:8200 /dev/#{@disk}")
66
- exec("sgdisk -n4:0:0 -t4:8302 /dev/#{@disk}") if @dev_home
67
- end
68
-
69
- def exec(cmd)
70
- Getch::Command.new(cmd).run!
44
+ @partition.gpt(@dev_gpt)
45
+ @partition.swap(@dev_swap)
46
+ @partition.root(@dev_root, "8304")
47
+ @partition.home(@dev_home, "8302") if @dev_home
71
48
  end
72
49
  end
73
50
  end
@@ -11,3 +11,4 @@ require_relative 'lvm/format'
11
11
  require_relative 'lvm/mount'
12
12
  require_relative 'lvm/config'
13
13
  require_relative 'lvm/deps'
14
+ require_relative 'lvm/encrypt'
@@ -16,23 +16,23 @@ module Getch
16
16
  end
17
17
 
18
18
  def systemd_boot
19
- return if ! Helpers::efi?
20
- esp = '/boot/efi'
19
+ return if !@efi
20
+ esp = '/efi'
21
21
  dir = "#{@root_dir}/#{esp}/loader/entries/"
22
22
  datas_gentoo = [
23
23
  'title Gentoo Linux',
24
24
  'linux /vmlinuz',
25
25
  'initrd /initramfs',
26
- "options resume=UUID=#{@uuid_swap} root=UUID=#{@uuid_root} init=#{@init} dolvm rw"
26
+ "options resume=#{@lv_swap} root=#{@lv_root} init=#{@init} dolvm rw"
27
27
  ]
28
28
  File.write("#{dir}/gentoo.conf", datas_gentoo.join("\n"))
29
29
  end
30
30
 
31
31
  def grub
32
- return if Helpers::efi?
32
+ return if @efi
33
33
  file = "#{@root_dir}/etc/default/grub"
34
34
  cmdline = [
35
- "GRUB_CMDLINE_LINUX=\"resume=UUID=#{@uuid_swap} root=UUID=#{@uuid_root} init=#{@init} dolvm rw\""
35
+ "GRUB_CMDLINE_LINUX=\"resume=#{@lv_swap} root=#{@lv_root} init=#{@init} dolvm rw\""
36
36
  ]
37
37
  File.write("#{file}", cmdline.join("\n"), mode: 'a')
38
38
  end
@@ -40,21 +40,18 @@ module Getch
40
40
  private
41
41
 
42
42
  def gen_uuid
43
- @uuid_swap = `lsblk -o "UUID" #{@lv_swap} | tail -1`.chomp() if @lv_swap
44
- @uuid_root = `lsblk -o "UUID" #{@lv_root} | tail -1`.chomp() if @lv_root
45
- @uuid_dev_root = `lsblk -o "UUID" #{@dev_root} | tail -1`.chomp() if @dev_root
46
43
  @uuid_boot = `lsblk -o "UUID" #{@dev_boot} | tail -1`.chomp() if @dev_boot
47
- @uuid_boot_efi = `lsblk -o "UUID" #{@dev_boot_efi} | tail -1`.chomp() if @dev_boot_efi
48
- @uuid_home = `lsblk -o "UUID" #{@lv_home} | tail -1`.chomp() if @lv_home
44
+ @uuid_esp = `lsblk -o "UUID" #{@dev_esp} | tail -1`.chomp() if @dev_esp
49
45
  end
50
46
 
51
47
  def data_fstab
52
- boot_efi = @dev_boot_efi ? "UUID=#{@uuid_boot_efi} /boot/efi vfat noauto,noatime 1 2" : ''
53
- swap = @lv_swap ? "UUID=#{@uuid_swap} none swap discard 0 0" : ''
54
- root = @lv_root ? "UUID=#{@uuid_root} / ext4 defaults 0 1" : ''
55
- home = @lv_home ? "UUID=#{@uuid_home} /home/#{@user} ext4 defaults 0 2" : ''
48
+ efi = @dev_esp ? "UUID=#{@uuid_esp} /efi vfat noauto,noatime 1 2" : ''
49
+ boot = @dev_boot ? "UUID=#{@uuid_boot} /boot ext4 noauto,noatime 1 2" : ''
50
+ swap = "#{@lv_swap} none swap discard 0 0"
51
+ root = "#{@lv_root} / ext4 defaults 0 1"
52
+ home = @lv_home ? "#{@lv_home} /home/#{@user} ext4 defaults 0 2" : ''
56
53
 
57
- [ boot_efi, swap, root, home ]
54
+ [ efi, boot, swap, root, home ]
58
55
  end
59
56
  end
60
57
  end
@@ -2,16 +2,9 @@ module Getch
2
2
  module FileSystem
3
3
  module Lvm
4
4
  class Deps
5
- def initialize
6
- if Helpers::efi?
7
- install_efi
8
- else
9
- install_bios
10
- end
11
- install_deps
12
- end
13
-
14
5
  def make
6
+ install_bios unless Helpers::efi?
7
+ install_deps
15
8
  options_make
16
9
  Getch::Make.new("genkernel --kernel-config=/usr/src/linux/.config all").run!
17
10
  end
@@ -34,22 +27,14 @@ module Getch
34
27
  File.write(file, datas.join("\n"), mode: 'a')
35
28
  end
36
29
 
37
- def install_efi
38
- end
39
-
40
- def install_bios
41
- exec("euse -p sys-boot/grub -E device-mapper")
42
- end
43
-
44
30
  def install_deps
45
- exec("euse -E lvm")
46
- Getch::Emerge.new('genkernel lvm2').pkg!
47
- Getch::Garden.new('-a lvm').run!
31
+ Getch::Bask.new('-a lvm').run!
32
+ Getch::Emerge.new('sys-fs/lvm2 genkernel').pkg!
48
33
  exec("systemctl enable lvm2-monitor")
49
34
  end
50
35
 
51
36
  def exec(cmd)
52
- Helpers::run_chroot(cmd, MOUNTPOINT)
37
+ Getch::Chroot.new(cmd).run!
53
38
  end
54
39
  end
55
40
  end
@@ -1,17 +1,41 @@
1
1
  module Getch
2
2
  module FileSystem
3
3
  module Lvm
4
- class Device
4
+ class Device < Getch::FileSystem::Device
5
5
  def initialize
6
- @disk = DEFAULT_OPTIONS[:disk]
7
- @user = DEFAULT_OPTIONS[:username]
8
- @dev_boot_efi = Helpers::efi? ? "/dev/#{@disk}1" : nil
9
- @dev_boot = Helpers::efi? ? nil : "/dev/#{@disk}2"
10
- @dev_root = Helpers::efi? ? "/dev/#{@disk}2" : "/dev/#{@disk}3"
6
+ super
11
7
  @vg = 'vg0'
12
- @lv_root = "/dev/mapper/#{@vg}-root"
13
- @lv_swap = "/dev/mapper/#{@vg}-swap"
14
- @lv_home = @user ? "/dev/mapper/#{@vg}-home" : nil
8
+ @lv_root = "/dev/#{@vg}/root"
9
+ @lv_swap = "/dev/#{@vg}/swap"
10
+ @lv_home = @home_disk ? "/dev/#{@vg}/home" : nil
11
+ end
12
+
13
+ private
14
+
15
+ def search_boot
16
+ if @efi
17
+ if @boot_disk
18
+ @dev_esp = "/dev/#{@boot_disk}1"
19
+ else
20
+ @dev_esp = "/dev/#{@disk}1"
21
+ @root_part += 1
22
+ end
23
+ else
24
+ if @boot_disk
25
+ @dev_gpt = "/dev/#{@boot_disk}1"
26
+ @dev_boot = "/dev/#{@boot_disk}2"
27
+ @dev_grub = "/dev/#{@boot_disk}"
28
+ else
29
+ @dev_gpt = "/dev/#{@disk}1"
30
+ @dev_boot = "/dev/#{@disk}2"
31
+ @dev_grub = "/dev/#{@disk}"
32
+ @root_part += 2
33
+ end
34
+ end
35
+ end
36
+
37
+ # The swap is a part of the LVM volume, so we clean the func
38
+ def search_swap
15
39
  end
16
40
  end
17
41
  end
@@ -0,0 +1,15 @@
1
+ module Getch
2
+ module FileSystem
3
+ module Lvm
4
+ module Encrypt
5
+ end
6
+ end
7
+ end
8
+ end
9
+
10
+ require_relative 'encrypt/device'
11
+ require_relative 'encrypt/partition'
12
+ require_relative 'encrypt/format'
13
+ require_relative 'encrypt/mount'
14
+ require_relative 'encrypt/config'
15
+ require_relative 'encrypt/deps'
@@ -0,0 +1,71 @@
1
+ module Getch
2
+ module FileSystem
3
+ module Lvm
4
+ module Encrypt
5
+ class Config < Getch::FileSystem::Lvm::Encrypt::Device
6
+ def initialize
7
+ super
8
+ gen_uuid
9
+ @root_dir = MOUNTPOINT
10
+ @init = '/usr/lib/systemd/systemd'
11
+ crypttab
12
+ end
13
+
14
+ def fstab
15
+ file = "#{@root_dir}/etc/fstab"
16
+ datas = data_fstab
17
+ File.write(file, datas.join("\n"))
18
+ end
19
+
20
+ def systemd_boot
21
+ return if ! Helpers::efi?
22
+ esp = '/efi'
23
+ dir = "#{@root_dir}/#{esp}/loader/entries/"
24
+ datas_gentoo = [
25
+ 'title Gentoo Linux',
26
+ 'linux /vmlinuz',
27
+ 'initrd /initramfs',
28
+ "options crypt_root=UUID=#{@uuid_dev_root} root=/dev/mapper/root real_root=#{@lv_root} init=#{@init} keymap=#{DEFAULT_OPTIONS[:keymap]} dolvm rw"
29
+ ]
30
+ File.write("#{dir}/gentoo.conf", datas_gentoo.join("\n"))
31
+ end
32
+
33
+ def crypttab
34
+ datas = [
35
+ "cryptswap #{@lv_swap} /dev/urandom swap,cipher=aes-xts-plain64:sha256,size=512"
36
+ ]
37
+ File.write("#{@root_dir}/etc/crypttab", datas.join("\n"))
38
+ end
39
+
40
+ def grub
41
+ return if Helpers::efi?
42
+ file = "#{@root_dir}/etc/default/grub"
43
+ cmdline = [
44
+ "GRUB_CMDLINE_LINUX=\"crypt_root=UUID=#{@uuid_dev_root} root=/dev/mapper/root real_root=#{@lv_root} init=#{@init} dolvm rw slub_debug=P page_poison=1 slab_nomerge pti=on vsyscall=none spectre_v2=on spec_store_bypass_disable=seccomp iommu=force keymap=#{DEFAULT_OPTIONS[:keymap]}\"",
45
+ "GRUB_ENABLE_CRYPTODISK=y"
46
+ ]
47
+ File.write("#{file}", cmdline.join("\n"), mode: 'a')
48
+ end
49
+
50
+ private
51
+
52
+ def gen_uuid
53
+ @uuid_dev_root = `lsblk -d -o "UUID" #{@dev_root} | tail -1`.chomp() if @dev_root
54
+ @uuid_boot = `lsblk -o "UUID" #{@dev_boot} | tail -1`.chomp() if @dev_boot
55
+ @uuid_esp = `lsblk -o "UUID" #{@dev_esp} | tail -1`.chomp() if @dev_esp
56
+ end
57
+
58
+ def data_fstab
59
+ boot_efi = @dev_esp ? "UUID=#{@uuid_esp} /efi vfat noauto,noatime 1 2" : ''
60
+ boot = @dev_boot ? "UUID=#{@uuid_boot} /boot ext4 noauto,noatime 1 2" : ''
61
+ swap = "/dev/mapper/cryptswap none swap discard 0 0"
62
+ root = "#{@lv_root} / ext4 defaults 0 1"
63
+ home = @lv_home ? "#{@lv_home} /home/#{@user} ext4 defaults 0 2" : ''
64
+
65
+ [ boot_efi, boot, swap, root, home ]
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,46 @@
1
+ module Getch
2
+ module FileSystem
3
+ module Lvm
4
+ module Encrypt
5
+ class Deps
6
+ def make
7
+ install_deps
8
+ options_make
9
+ Getch::Make.new("genkernel --kernel-config=/usr/src/linux/.config all").run!
10
+ end
11
+
12
+ private
13
+ def options_make
14
+ grub = Helpers::efi? ? 'BOOTLOADER="no"' : 'BOOTLOADER="grub2"'
15
+ datas = [
16
+ '',
17
+ grub,
18
+ 'INSTALL="yes"',
19
+ 'MENUCONFIG="no"',
20
+ 'CLEAN="yes"',
21
+ 'KEYMAP="yes"',
22
+ 'SAVE_CONFIG="yes"',
23
+ 'MOUNTBOOT="yes"',
24
+ 'MRPROPER="no"',
25
+ 'LVM="yes"',
26
+ 'LUKS="yes"',
27
+ ]
28
+ file = "#{MOUNTPOINT}/etc/genkernel.conf"
29
+ File.write(file, datas.join("\n"), mode: 'a')
30
+ end
31
+
32
+ def install_deps
33
+ # lvm2, cryptsetup alrealy installed
34
+ Getch::Bask.new('-a lvm').run!
35
+ Getch::Emerge.new('genkernel').pkg!
36
+ exec("systemctl enable lvm2-monitor")
37
+ end
38
+
39
+ def exec(cmd)
40
+ Getch::Chroot.new(cmd).run!
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end