diff --git a/ggpalette.R b/ggpalette.R
new file mode 100755
index 0000000000000000000000000000000000000000..7794f2e0ecdc7560a9514c7a1aa94514855d946c
--- /dev/null
+++ b/ggpalette.R
@@ -0,0 +1,134 @@
+#' @title ggpalette
+#' @description
+#' provide colors used by ggplot2
+#' the interest is to use another single color that is not the red one used by default
+#' for ggplot2 specifications, see: https://ggplot2.tidyverse.org/articles/ggplot2-specs.html
+#' @param n number of groups on the graph.
+#' @param kind either "std" for standard gg colors, "dark" for darkened gg colors, or "light" for pastel gg colors.
+#' @returns the vector of hexadecimal colors.
+#' @examples
+#' ggpalette(n = 2) # output of the function
+#'    
+#' plot(1:7, pch = 16, cex = 5, col = ggpalette(n = 7)) # the ggplot2 palette when asking for 7 different colors
+#'   
+#' plot(1:7, pch = 16, cex = 5, col = ggpalette(n = 7)[5]) # selection of the 5th color of the ggplot2 palette made of 7 different colors
+#'    
+#' plot(1:7, pch = 16, cex = 5, col = ggpalette(n = 7, kind = "dark")) # the ggplot2 palette made of 7 darkened colors
+#'    
+#' plot(1:7, pch = 16, cex = 5, col = ggpalette(n = 7, kind = "light")) # the ggplot2 palette made of 7 lighten colors
+#' @importFrom utils find
+#' @importFrom saferDev arg_check
+#' @export
+    ggpalette <- function(
+        n, 
+        kind = "std"
+    ){
+    # DEBUGGING
+    # n = 0 ; kind = "std"
+    # package name
+    package.name <- "ggcute"
+    # end package name
+    # function name
+    function.name <- base::paste0(base::as.list(base::match.call(expand.dots = FALSE))[[1]], "()") # function name with "()" paste, which split into a vector of three: c("::()", "package()", "function()") if "package::function()" is used.
+    if(function.name[1] == "::()"){
+        function.name <- function.name[3]
+    }
+    arg.names <- base::names(base::formals(fun = base::sys.function(base::sys.parent(n = 2)))) # names of all the arguments
+    arg.user.setting <- base::as.list(base::match.call(expand.dots = FALSE))[-1] # list of the argument settings (excluding default values not provided by the user)
+    # end function name
+    # critical operator checking
+    .base_op_check(external.function.name = function.name)
+    # end critical operator checking
+    # package checking
+    # check of lib.path
+    # end check of lib.path
+    # check of the required function from the required packages
+    .pack_and_function_check(
+        fun = base::c(
+            "saferDev::arg_check",
+            "utils::find"
+        ),
+        lib.path = NULL,
+        external.function.name = function.name
+    )
+    # end check of the required function from the required packages
+    # end package checking
+
+    # argument primary checking
+    # arg with no default values
+    mandat.args <- base::c(
+        "n"
+    )
+    tempo <- base::eval(base::parse(text = base::paste0("missing(", base::paste0(mandat.args, collapse = ") | missing("), ")")))
+    if(base::any(tempo)){ # normally no NA for missing() output
+        tempo.cat <- base::paste0("ERROR IN ", function.name, " OF THE ", package.name, " PACKAGE\nFOLLOWING ARGUMENT", base::ifelse(base::sum(tempo, na.rm = TRUE) > 1, "S HAVE", "HAS"), " NO DEFAULT VALUE AND REQUIRE ONE:\n", base::paste0(mandat.args, collapse = "\n"))
+        base::stop(base::paste0("\n\n================\n\n", tempo.cat, "\n\n================\n\n"), call. = FALSE) # == in stop() to be able to add several messages between ==
+    }
+    # end arg with no default values
+    # argument checking with arg_check()    
+    # argument checking
+    argum.check <- NULL #
+    text.check <- NULL #
+    checked.arg.names <- NULL # for function debbuging: used by r_debugging_tools
+    ee <- base::expression(argum.check <- c(argum.check, tempo$problem) , text.check <- c(text.check, tempo$text) , checked.arg.names <- base::c(checked.arg.names, tempo$object.name))
+    tempo <- saferDev::arg_check(data = n, class = "integer", length = 1, double.as.integer.allowed = TRUE, neg.values = FALSE, fun.name = function.name) ; base::eval(ee)
+    tempo <- saferDev::arg_check(data = kind, options = c("std", "dark", "light"), length = 1, fun.name = function.name) ; base::eval(ee)
+
+    if( ! base::is.null(argum.check)){
+        if(base::any(argum.check, na.rm = TRUE) == TRUE){
+            base::stop(base::paste0("\n\n================\n\n", base::paste(text.check[argum.check], collapse = "\n"), "\n\n================\n\n"), call. = FALSE) #
+        }
+    }
+    # end argument checking with arg_check()
+    # check with r_debugging_tools
+    # source("C:/Users/yhan/Documents/Git_projects/debugging_tools_for_r_dev/r_debugging_tools.R") ; eval(parse(text = str_basic_arg_check_dev)) ; eval(parse(text = str_arg_check_with_fun_check_dev)) # activate this line and use the function (with no arguments left as NULL) to check arguments status and if they have been checked using arg_check()
+    # end check with r_debugging_tools
+    # end argument primary checking
+
+    # second round of checking and data preparation
+    # management of NA arguments
+    if( ! (base::all(base::class(arg.user.setting) == "list", na.rm = TRUE) & base::length(arg.user.setting) == 0)){
+        tempo.arg <- base::names(arg.user.setting) # values provided by the user
+        tempo.log <- base::suppressWarnings(base::sapply(base::lapply(base::lapply(tempo.arg, FUN = base::get, envir = base::sys.nframe(), inherits = FALSE), FUN = base::is.na), FUN = base::any)) & base::lapply(base::lapply(tempo.arg, FUN = base::get, envir = base::sys.nframe(), inherits = FALSE), FUN = base::length) == 1L # no argument provided by the user can be just NA
+        if(base::any(tempo.log) == TRUE){ # normally no NA because is.na() used here
+            tempo.cat <- base::paste0("ERROR IN ", function.name, " OF THE ", package.name, " PACKAGE\n", base::ifelse(base::sum(tempo.log, na.rm = TRUE) > 1, "THESE ARGUMENTS", "THIS ARGUMENT"), " CANNOT JUST BE NA:", base::paste0(tempo.arg[tempo.log], collapse = "\n"))
+            base::stop(base::paste0("\n\n================\n\n", tempo.cat, "\n\n================\n\n"), call. = FALSE) # == in stop() to be able to add several messages between ==
+        }
+    }
+    # end management of NA arguments
+    # management of NULL arguments
+    tempo.arg <-base::c(
+        "n" ,
+        "kind" 
+    )
+    tempo.log <- base::sapply(base::lapply(tempo.arg, FUN = base::get, envir = base::sys.nframe(), inherits = FALSE), FUN = base::is.null)
+    if(base::any(tempo.log) == TRUE){# normally no NA with is.null()
+        tempo.cat <- base::paste0("ERROR IN ", function.name, " OF THE ", package.name, " PACKAGE:\n", base::ifelse(base::sum(tempo.log, na.rm = TRUE) > 1, "THESE ARGUMENTS\n", "THIS ARGUMENT\n"), base::paste0(tempo.arg[tempo.log], collapse = "\n"),"\nCANNOT BE NULL")
+        base::stop(base::paste0("\n\n================\n\n", tempo.cat, "\n\n================\n\n"), call. = FALSE) # == in stop() to be able to add several messages between ==
+    }
+    # end management of NULL arguments
+    # code that protects set.seed() in the global environment
+    # end code that protects set.seed() in the global environment
+    # warning initiation
+    # end warning initiation
+    # other checkings
+    if(base::isTRUE(base::all.equal(n, 0))){ # isTRUE(all.equal(n, 0))) is similar to n == 0 but deals with float
+        tempo.cat <- base::paste0("ERROR IN ", function.name, " OF THE ", package.name, " PACKAGE:\nn ARGUMENT MUST BE A NON ZERO INTEGER. HERE IT IS: ", base::paste(n, collapse = " "))
+            base::stop(base::paste0("\n\n================\n\n", tempo.cat, "\n\n================\n\n"), call. = FALSE) # == in stop() to be able to add several messages between ==
+    }
+
+    # end other checkings
+    # reserved words (to avoid bugs)
+    # end reserved words (to avoid bugs)
+    # end second round of checking and data preparation
+    # main code
+    hues = base::seq(15, 375, length = n + 1)
+    output <- base::hcl(h = hues, l = if(kind == "std"){65}else if(kind == "dark"){35}else if(kind == "light"){85}, c = 100)[1:n]
+
+    # end main code
+    # output
+    # warning output
+    # end warning output
+    base::return(output) # do not use cat() because the idea is to reuse the message
+    # end output
+}
\ No newline at end of file