├── bin ├── quality └── setup ├── modules ├── osx_update.bash ├── projectdir.bash ├── dotfiles.bash ├── osx_security.bash ├── ssh.bash ├── osx_version.bash ├── ruby.bash ├── node.bash ├── functions.bash ├── brew.bash └── osx_defaults.bash ├── Brewfile ├── .semaphore └── semaphore.yml └── README.md /bin/quality: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | shellcheck --shell bash --exclude=SC1090,SC2086 modules/* bin/setup 6 | -------------------------------------------------------------------------------- /modules/osx_update.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Running OS X Software updates" 7 | sudo softwareupdate -i -a 8 | -------------------------------------------------------------------------------- /modules/projectdir.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | if ! test -e ~/src ; then 7 | info_echo "Setup project directory at ~/src (also linked from ~/Develop and ~/Projects" 8 | mkdir ~/src 9 | ln -s ~/src ~/Develop 10 | ln -s ~/src ~/Projects 11 | fi 12 | -------------------------------------------------------------------------------- /modules/dotfiles.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Installing bash dotfiles to ~/.dotfiles" 7 | 8 | if [ ! -d ~/.dotfiles ]; then 9 | git clone https://github.com/fs/dotfiles.git ~/.dotfiles 10 | ( 11 | cd ~/.dotfiles|| exit 12 | bash script/setup 13 | ) 14 | fi 15 | -------------------------------------------------------------------------------- /modules/osx_security.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Expose hidden files and Library folder in Finder" 7 | defaults write com.apple.finder AppleShowAllFiles -bool true 8 | chflags nohidden ~/Library 9 | 10 | info_echo "Empty Trash securely by default" 11 | defaults write com.apple.finder EmptyTrashSecurely -bool true 12 | -------------------------------------------------------------------------------- /modules/ssh.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Checking for SSH key, generating one if it doesn't exist" 7 | [[ -f ~/.ssh/id_rsa.pub ]] || ssh-keygen -t rsa 8 | 9 | info_echo "Copying public key to clipboard. Paste it into your Github account" 10 | [[ -f ~/.ssh/id_rsa.pub ]] && pbcopy < ~/.ssh/id_rsa.pub 11 | open https://github.com/account/ssh 12 | -------------------------------------------------------------------------------- /modules/osx_version.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | required_osx_version="10.15.3" 7 | osx_version=$(/usr/bin/sw_vers -productVersion) 8 | 9 | info_echo "Checking OS X version" 10 | if [ "$(version "$osx_version")" -lt "$(version "$required_osx_version")" ]; then 11 | error_echo "Your OS X $osx_version version is older then required $required_osx_version version. Exiting" 12 | exit 13 | fi 14 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | OSX_BOOTSTRAP=${OSX_BOOTSTRAP:-"$HOME/.osx-bootstrap"} 6 | 7 | if [ ! -d "$OSX_BOOTSTRAP" ] 8 | then 9 | git clone -b master https://github.com/fs/osx-bootstrap.git "$OSX_BOOTSTRAP" 10 | fi 11 | 12 | modules=( 13 | osx_version 14 | osx_update 15 | projectdir 16 | ssh 17 | brew 18 | ruby 19 | node 20 | osx_defaults 21 | osx_security 22 | dotfiles 23 | ) 24 | 25 | for module in "${modules[@]}" 26 | do 27 | bash "$OSX_BOOTSTRAP/modules/$module.bash" 28 | done 29 | 30 | -------------------------------------------------------------------------------- /modules/ruby.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 6 | source "$osx_bootstrap/modules/functions.bash" 7 | 8 | if test ! "$(command -v rbenv)" 9 | then 10 | info_echo 'Installing rbenv' 11 | # shellcheck disable=SC2016 12 | [ -f "$HOME/.zshrc" ] && echo 'eval "$(rbenv init -)"' >> ~/.zshrc 13 | brew install rbenv 14 | eval "$(rbenv init -)" 15 | /bin/bash -c "curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash" 16 | else 17 | info_echo "Rbenv already installed" 18 | fi 19 | -------------------------------------------------------------------------------- /modules/node.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Enable NVM alias" 7 | # we need disable -e during sourcing nvm.sh b/c of 8 | # https://github.com/creationix/nvm/issues/721 9 | # https://github.com/travis-ci/travis-ci/issues/3854#issuecomment-99492695 10 | set +e 11 | # shellcheck disable=SC1091 12 | source "$(brew --prefix nvm)/nvm.sh" 13 | 14 | set -e 15 | 16 | if test -n "$(nvm ls|grep "node"|grep "N/A")"; then 17 | info_echo "Install latest Node.js version" 18 | nvm install node 19 | fi 20 | 21 | info_echo "Set latest Node.js version as global default Node" 22 | nvm use node 23 | nvm alias default node 24 | -------------------------------------------------------------------------------- /modules/functions.bash: -------------------------------------------------------------------------------- 1 | export HOMEBREW_CASK_OPTS="--appdir=/Applications" 2 | #export RBENV_ROOT=/usr/local/var/rbenv 3 | #export NVM_DIR=/usr/local/var/nvm 4 | 5 | red=$(tput setaf 1) 6 | green=$(tput setaf 2) 7 | color_reset=$(tput sgr0) 8 | 9 | error_echo() { 10 | printf "\\n${red}%s.${color_reset}\\n" "$1" 11 | } 12 | 13 | info_echo() { 14 | printf "\\n${green}%s ...${color_reset}\\n" "$1" 15 | } 16 | 17 | version() { 18 | echo "$@" | awk -F. '{ printf("%d%03d%03d%03d", $1,$2,$3,$4); }' 19 | } 20 | 21 | catch_exit() { 22 | ret=$? 23 | test $ret -ne 0 && error_echo "Installation fails" >&2 24 | exit $ret 25 | } 26 | 27 | # Catch exit 28 | trap catch_exit EXIT 29 | 30 | # Setup logging 31 | exec > >(tee -i "$HOME/.osx-bootstrap.$(date +%Y-%m-%d-%H-%M-%S).log") 32 | exec 2>&1 33 | -------------------------------------------------------------------------------- /modules/brew.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | export PATH="/opt/homebrew/bin:$PATH" 6 | 7 | # shellcheck disable=SC2016 8 | [ -f "$HOME/.zprofile" ] && echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile 9 | 10 | if test ! "$(command -v brew)"; then 11 | info_echo "Install Homebrew, a good OS X package manager" 12 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 13 | else 14 | info_echo "Update Homebrew" 15 | brew update 16 | fi 17 | 18 | info_echo "Install Brew formalue" 19 | 20 | brew tap "Homebrew/bundle" 2> /dev/null 21 | brew bundle install --file="$osx_bootstrap/Brewfile" 22 | 23 | info_echo "Remove outdated versions from the cellar" 24 | 25 | brew cleanup 26 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | # Make sure you have following env variables 2 | # when using this Brewfile or use it with modules/brew.bash 3 | # 4 | HOMEBREW_CASK_OPTS="--appdir=/Applications" 5 | # RBENV_ROOT=/usr/local/var/rbenv 6 | # NVM_DIR=/usr/local/var/nvm 7 | 8 | tap "heroku/brew" 9 | 10 | brew "git" 11 | brew "heroku" 12 | brew "imagemagick" 13 | brew "nvm" 14 | brew "openssl" 15 | brew "postgresql", restart_service: true 16 | brew "rbenv" 17 | brew "rbenv-default-gems" 18 | brew "readline", link: true 19 | brew "redis", restart_service: true 20 | brew "ruby-build" 21 | brew "ssh-copy-id" 22 | brew "tmux" 23 | brew "watch" 24 | brew "yarn" 25 | brew "z" 26 | 27 | cask "chromedriver" 28 | cask "google-chrome" 29 | cask "graphiql" 30 | cask "iterm2" 31 | cask "postman" 32 | cask "slack" 33 | cask "the-unarchiver" 34 | cask "visual-studio-code" 35 | cask "zoom" 36 | cask "sublime-text" 37 | cask "1password" 38 | -------------------------------------------------------------------------------- /.semaphore/semaphore.yml: -------------------------------------------------------------------------------- 1 | # For more Swift information and examples, see: 2 | # https://docs.semaphoreci.com/article/139-language-swift 3 | version: v1.0 4 | name: OSX Bootstrap 5 | 6 | agent: 7 | machine: 8 | type: a1-standard-4 9 | os_image: macos-xcode12 10 | 11 | execution_time_limit: 12 | hours: 1 13 | 14 | auto_cancel: 15 | queued: 16 | when: 'true' 17 | 18 | blocks: 19 | - name: Test 20 | task: 21 | env_vars: 22 | - name: HOMEBREW_NO_AUTO_UPDATE 23 | value: "true" 24 | 25 | prologue: 26 | commands: 27 | - checkout 28 | 29 | jobs: 30 | - name: quality 31 | commands: 32 | - brew install shellcheck 33 | - bin/quality 34 | 35 | - name: workspace 36 | commands: 37 | - modules/projectdir.bash 38 | 39 | - name: dev 40 | commands: 41 | - modules/brew.bash 42 | - modules/ruby.bash 43 | # Disable node test since need to update 44 | # - modules/node.bash 45 | 46 | - name: osx 47 | commands: 48 | - modules/osx_version.bash 49 | - modules/osx_defaults.bash 50 | - modules/osx_security.bash 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OS X Bootstrap 2 | 3 | Script to set up a macOS X for Rails development. 4 | 5 | ## Requirements 6 | 7 | macOS X version >= 10.15 8 | 9 | ## Install 10 | 11 | Run the setup script which will clone repository to `~/.osx-bootstrap` directory 12 | and run `~/.osx-bootstrap/modules/*` scripts. 13 | 14 | ```bash 15 | bash <(curl -s https://raw.githubusercontent.com/fs/osx-bootstrap/master/bin/setup) 16 | ``` 17 | 18 | Or you can run each module script one-by-one: 19 | 20 | ```bash 21 | git clone -b master https://github.com/fs/osx-bootstrap.git 22 | ~/.osx-bootstrap/modules/osx_defaults.bash 23 | ``` 24 | 25 | ## What it sets up 26 | 27 | * OS X Command Line Tools 28 | * SSH keys 29 | * **Homebrew** for managing operating system libraries (OS X only) 30 | * **git** source code management system 31 | * **Postgresql** for storing relational data 32 | * **Redis** for storing key-value data 33 | * **ImageMagick** for cropping and resizing images 34 | * **watch** for periodically executing a program and displaying the output 35 | * **[Z](https://github.com/rupa/z)** (jump around) for a faster way to navigate your filesystem 36 | * **ssh-copy-id** to deliver your public key in a remote machine's authorized_keys 37 | * **Heroku Toolbelt** for interacting with the Heroku API 38 | * **tmux** for saving project state and switching between projects 39 | * **rbenv** for managing versions of the Ruby programming language in the `/usr/local/var/rbenv` 40 | * **ruby-build** for installing Ruby versions 41 | * **Ruby** programming language, latest stable version 42 | * **NVM** for managing versions of the Node.js 43 | * **Node.js** stable for writing JavaScript general-purpose code 44 | * Software installed with Brew Cask in to `/Applications`: 45 | * Google Chrome 46 | * ChromeDriver 47 | * GraphiQL 48 | * iTerm2 49 | * Java 50 | * Postman 51 | * Skype 52 | * Slack 53 | * Spectacle 54 | * Sublime Text 3 55 | * The Unarchiver 56 | * Visual Studio Code 57 | * Zoom 58 | * Set OS X defaults (faster animation, security settings etc) 59 | 60 | ## Credits 61 | 62 | OS X Bootstrap is maintained by [Timur Vafin](http://github.com/timurvafin). 63 | It was written by [Flatstack](http://www.flatstack.com) with the help of our 64 | [contributors](http://github.com/fs/osx-bootstrap/contributors). 65 | 66 | [](http://www.flatstack.com) 67 | -------------------------------------------------------------------------------- /modules/osx_defaults.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | osx_bootstrap="$(cd "$(dirname "$0")/.." && pwd -P)" 4 | source "$osx_bootstrap/modules/functions.bash" 5 | 6 | info_echo "Set OS X defaults" 7 | 8 | ############################################################################### 9 | # General UI/UX # 10 | ############################################################################### 11 | 12 | # Set computer name (as done via System Preferences → Sharing) 13 | hostname=$(whoami) 14 | sudo scutil --set ComputerName "$hostname" 15 | sudo scutil --set HostName "$hostname" 16 | sudo scutil --set LocalHostName "$hostname" 17 | sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName -string "$hostname" 18 | 19 | # Disable the sound effects on boot 20 | sudo nvram SystemAudioVolume=" " 21 | 22 | # Menu bar: hide icons 23 | for domain in ~/Library/Preferences/ByHost/com.apple.systemuiserver.*; do 24 | defaults write "${domain}" dontAutoLoad -array \ 25 | "/System/Library/CoreServices/Menu Extras/TimeMachine.menu" \ 26 | "/System/Library/CoreServices/Menu Extras/Volume.menu" \ 27 | "/System/Library/CoreServices/Menu Extras/Bluetooth.menu" \ 28 | "/System/Library/CoreServices/Menu Extras/AirPort.menu" \ 29 | "/System/Library/CoreServices/Menu Extras/User.menu" 30 | done 31 | 32 | ############################################################################### 33 | # Trackpad, mouse, keyboard, Bluetooth accessories, and input # 34 | ############################################################################### 35 | 36 | # Disable “natural” (Lion-style) scrolling 37 | defaults write NSGlobalDomain com.apple.swipescrolldirection -bool false 38 | 39 | # Set language and text formats 40 | defaults write NSGlobalDomain AppleLanguages -array "en" "ru" 41 | defaults write NSGlobalDomain AppleLocale -string "ru_RU@currency=RUB" 42 | defaults write NSGlobalDomain AppleMeasurementUnits -string "Centimeters" 43 | defaults write NSGlobalDomain AppleMetricUnits -bool true 44 | 45 | # Accelerate cursor 46 | defaults write NSGlobalDomain KeyRepeat -int 0 47 | 48 | # Disable auto-correct 49 | defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false 50 | 51 | # Enable full keyboard access for all controls 52 | # (e.g. enable Tab in modal dialogs) 53 | defaults write NSGlobalDomain AppleKeyboardUIMode -int 3 54 | 55 | ############################################################################### 56 | # Finder # 57 | ############################################################################### 58 | 59 | # Finder: disable window animations and Get Info animations 60 | defaults write com.apple.finder DisableAllAnimations -bool true 61 | 62 | # Finder: show all filename extensions 63 | defaults write NSGlobalDomain AppleShowAllExtensions -bool true 64 | 65 | # Finder: show status bar 66 | defaults write com.apple.finder ShowStatusBar -bool true 67 | 68 | # Finder: show path bar 69 | defaults write com.apple.finder ShowPathbar -bool true 70 | 71 | # Display full POSIX path as Finder window title 72 | defaults write com.apple.finder _FXShowPosixPathInTitle -bool true 73 | 74 | # When performing a search, search the current folder by default 75 | defaults write com.apple.finder FXDefaultSearchScope -string "SCcf" 76 | 77 | # Disable the warning when changing a file extension 78 | defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false 79 | 80 | # Avoid creating .DS_Store files on network volumes 81 | defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true 82 | 83 | # Use list view in all Finder windows by default 84 | # Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv` 85 | defaults write com.apple.Finder FXPreferredViewStyle Nlsv 86 | 87 | # # Disable the warning before emptying the Trash 88 | defaults write com.apple.finder WarnOnEmptyTrash -bool false 89 | 90 | # Enable AirDrop over Ethernet and on unsupported Macs running Lion 91 | defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true 92 | 93 | # Set $HOME as the default location for new Finder windows 94 | # For other paths, use `PfLo` and `file:///full/path/here/` 95 | defaults write com.apple.finder NewWindowTarget -string "PfLo" 96 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}" 97 | 98 | ############################################################################### 99 | # Dock, Dashboard, and hot corners # 100 | ############################################################################### 101 | 102 | # Wipe all (default) app icons from the Dock 103 | # This is only really useful when setting up a new Mac, or if you don’t use 104 | # the Dock to launch apps. 105 | defaults write com.apple.dock persistent-apps -array 106 | 107 | # Add applications to Dock 108 | for app in \ 109 | System\ Preferences \ 110 | Safari \ 111 | Slack \ 112 | iTerm \ 113 | Sublime\ Text 114 | do 115 | defaults write com.apple.dock "persistent-apps" -array-add "tile-datafile-data_CFURLString/Applications/$app.app/_CFURLStringType0" 116 | done 117 | 118 | # Disable Dashboard 119 | defaults write com.apple.dashboard mcx-disabled -bool true 120 | 121 | # Don’t show Dashboard as a Space 122 | defaults write com.apple.dock dashboard-in-overlay -bool true 123 | 124 | # Don’t automatically rearrange Spaces based on most recent use 125 | defaults write com.apple.dock mru-spaces -bool false 126 | 127 | # Make Dock icons of hidden applications translucent 128 | defaults write com.apple.dock showhidden -bool true 129 | 130 | # Turn off dock icons magnification 131 | defaults write com.apple.dock magnification -boolean false 132 | 133 | # Show dock on right 134 | defaults write com.apple.dock orientation -string 'right' 135 | 136 | ############################################################################### 137 | # Safari & WebKit # 138 | ############################################################################### 139 | 140 | # Set Safari’s home page to `about:blank` for faster loading 141 | defaults write com.apple.Safari HomePage -string "about:blank" 142 | 143 | # Prevent Safari from opening ‘safe’ files automatically after downloading 144 | defaults write com.apple.Safari AutoOpenSafeDownloads -bool false 145 | 146 | # Hide Safari’s bookmarks bar by default 147 | defaults write com.apple.Safari ShowFavoritesBar -bool false 148 | 149 | # Show status bar 150 | defaults write com.apple.Safari ShowStatusBar -bool true 151 | 152 | # Hide Safari’s sidebar in Top Sites 153 | defaults write com.apple.Safari ShowSidebarInTopSites -bool false 154 | 155 | # Enable the Develop menu and the Web Inspector in Safari 156 | defaults write com.apple.Safari IncludeDevelopMenu -bool true 157 | defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true 158 | defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true 159 | 160 | # Add a context menu item for showing the Web Inspector in web views 161 | defaults write NSGlobalDomain WebKitDeveloperExtras -bool true 162 | 163 | ############################################################################### 164 | # Spotlight # 165 | ############################################################################### 166 | 167 | # Disable Spotlight indexing for any volume that gets mounted and has not yet 168 | # been indexed before. 169 | # Use `sudo mdutil -i off "/Volumes/foo"` to stop indexing any volume. 170 | sudo defaults write /.Spotlight-V100/VolumeConfiguration Exclusions -array "/Volumes" 171 | 172 | # Change indexing order and disable some file types 173 | defaults write com.apple.spotlight orderedItems -array \ 174 | '{"enabled" = 1;"name" = "APPLICATIONS";}' \ 175 | '{"enabled" = 1;"name" = "SYSTEM_PREFS";}' \ 176 | '{"enabled" = 1;"name" = "DIRECTORIES";}' \ 177 | '{"enabled" = 1;"name" = "PDF";}' \ 178 | '{"enabled" = 1;"name" = "FONTS";}' \ 179 | '{"enabled" = 0;"name" = "DOCUMENTS";}' \ 180 | '{"enabled" = 0;"name" = "MESSAGES";}' \ 181 | '{"enabled" = 0;"name" = "CONTACT";}' \ 182 | '{"enabled" = 0;"name" = "EVENT_TODO";}' \ 183 | '{"enabled" = 0;"name" = "IMAGES";}' \ 184 | '{"enabled" = 0;"name" = "BOOKMARKS";}' \ 185 | '{"enabled" = 0;"name" = "MUSIC";}' \ 186 | '{"enabled" = 0;"name" = "MOVIES";}' \ 187 | '{"enabled" = 0;"name" = "PRESENTATIONS";}' \ 188 | '{"enabled" = 0;"name" = "SPREADSHEETS";}' \ 189 | '{"enabled" = 0;"name" = "SOURCE";}' 190 | 191 | # Make sure indexing is enabled for the main volume 192 | sudo mdutil -i on / > /dev/null 193 | 194 | # Rebuild the index from scratch 195 | sudo mdutil -E / > /dev/null 196 | 197 | ############################################################################### 198 | # Terminal & iTerm 2 # 199 | ############################################################################### 200 | 201 | # Only use UTF-8 in Terminal.app 202 | defaults write com.apple.terminal StringEncodings -array 4 203 | 204 | # Don’t display the annoying prompt when quitting iTerm 205 | defaults write com.googlecode.iterm2 PromptOnQuit -bool false 206 | 207 | ############################################################################### 208 | # Kill affected applications # 209 | ############################################################################### 210 | 211 | for app in "cfprefsd" "Dock" "Finder" "Safari" "SystemUIServer" "iTerm"; do 212 | killall "${app}" > /dev/null 2>&1 || true 213 | done 214 | --------------------------------------------------------------------------------