问:
JAVA SimpleDateFormat on ArrayList changes Date
I'm populating a 'ListView' with an 'ArrayList' using an Adapter.
The 'ArrayList' contains objects with date and time.
When i send the data as it is to the ListView, there is no problem, and the list shows the relevant objects as desired :

```<code>public View getView(int position, View convertView, ViewGroup parent) {

  TimePeriod freeSlot = (TimePeriod)getItem(position);

  if (convertView == null) {
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.item, parent, false);
    }

    TextView start = (TextView) convertView.findViewById(R.id.start);
    TextView end = (TextView) convertView.findViewById(R.id.end);

    startTime = freeSlot.getStart().toString()
    endTime = freeSlot.getEnd().toString();
    start.setText(startTime);
    end.setText(endTime);

    return convertView;
}
</code>```

2017-07-05T10:30:00.000Z 2017-07-05T11:30:00.000Z

But when i use SimpleDateFormat to change the output as i want, it somehow sets the dates of all objects to the same one (01/01) :

```<code>startTime = freeSlot.getStart().toString();
endTime = freeSlot.getEnd().toString();

try {
            SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss.SSS'Z'");
            Date newDate = formatter.parse(startTime);
            Date newDate2 = formatter.parse(endTime);

            SimpleDateFormat format = new SimpleDateFormat("dd/MM hh:mm");
            startTime = format.format(newDate);
            SimpleDateFormat format1 = new SimpleDateFormat("hh:mm");
            endTime = format1.format(newDate2);

        } catch (ParseException pe) {
            pe.printStackTrace();
        }

        start.setText(startTime);
        end.setText(endTime);
</code>```

for start - 01/01 10:30, for end - 11:30

As iv'e mentioned earlier, all objects get this date even though dates & hours are different.

Any ideas? What am i doing wrong?
Thanks a lot!

答:
use something like this to make it easy,
Create a util class with Below Methods:

```<code> /**
     * Parses @date to String in provided @format
     *
     * @param date   Date
     * @param format Convert to Format
     * @return formatted date string
     */
    public static String DateToString(Date date, String format) {
        if (date != null) {
            try {
                DateFormat dateFormat = new SimpleDateFormat(format);
                return dateFormat.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        } else {
            return "";
        }
    }

    /**
     * Parses date to String in provided format
     *
     * @param date   Date
     * @param format Convert to Format
     * @return formatted date string
     */
    public static String DateToString(Date date, Format format) {
        if (date != null) {
            try {
                DateFormat dateFormat = new SimpleDateFormat(format.format);
                return dateFormat.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        } else {
            return "";
        }
    }
</code>```

Create static enum/String Format for Reusability. such as below :

```<code> public static enum Format {

        /**
         * "EEE, MMM dd, yyyy, hh:mm a"
         */
        FORMAT1("EEE, MMM dd, yyyy, hh:mm a"),
        /**
         * "dd/MM/yyyy"
         */
        FORMAT2("dd/MM/yyyy"),
        /**
         * "dd/MM/yyyy hh:mm a"
         */
        FORMAT3("dd/MM/yyyy hh:mm a"),
        /**
         * "dd/MM/yyyy hh:mm:ss a"
         */
        FORMAT4("dd/MM/yyyy hh:mm:ss a"),
        /**
         * "dd/MM/yyyy HH:mm"
         */
        FORMAT5("dd/MM/yyyy HH:mm"),
        /**
         * "dd/MM/yyyy HH:mm:ss"
         */
        FORMAT6("dd/MM/yyyy HH:mm:ss"),
        /**
         * "dd-MM-yyyy"
         */
        FORMAT7("dd-MM-yyyy"),
        /**
         * "dd-MM-yyyy hh:mm a"
         */
        FORMAT8("dd-MM-yyyy hh:mm a"),
        /**
         * "dd-MM-yyyy hh:mm:ss a"
         */
        FORMAT9("dd-MM-yyyy hh:mm:ss a"),
        /**
         * "dd-MM-yyyy HH:mm"
         */
        FORMAT10("dd-MM-yyyy HH:mm"),
        /**
         * "dd-MM-yyyy HH:mm:ss"
         */
        FORMAT11("dd-MM-yyyy HH:mm:ss"),
        /**
         * "MM/dd/yyyy"
         */
        FORMAT12("MM/dd/yyyy"),
        /**
         * "MM/dd/yyyy hh:mm a"
         */
        FORMAT13("MM/dd/yyyy hh:mm a"),
        /**
         * "MM/dd/yyyy hh:mm:ss a"
         */
        FORMAT14("MM/dd/yyyy hh:mm:ss a"),
        /**
         * "MM/dd/yyyy HH:mm"
         */
        FORMAT15("MM/dd/yyyy HH:mm"),
        /**
         * "MM/dd/yyyy HH:mm:ss"
         */
        FORMAT16("MM/dd/yyyy HH:mm:ss"),
        /**
         * "MM-dd-yyyy"
         */
        FORMAT17("MM-dd-yyyy"),
        /**
         * "MM-dd-yyyy hh:mm a"
         */
        FORMAT18("MM-dd-yyyy hh:mm a"),
        /**
         * "MM-dd-yyyy hh:mm:ss a"
         */
        FORMAT19("MM-dd-yyyy hh:mm:ss a"),
        /**
         * "MM-dd-yyyy HH:mm"
         */
        FORMAT20("MM-dd-yyyy HH:mm"),
        /**
         * "MM-dd-yyyy HH:mm:ss"
         */
        FORMAT21("MM-dd-yyyy HH:mm:ss"),
        /**
         * "yyyy/MM/dd"
         */
        FORMAT22("yyyy/MM/dd"),
        /**
         * "yyyy/MM/dd hh:mm a"
         */
        FORMAT23("yyyy/MM/dd hh:mm a"),
        /**
         * "yyyy/MM/dd hh:mm:ss a"
         */
        FORMAT24("yyyy/MM/dd hh:mm:ss a"),
        /**
         * "yyyy/MM/dd HH:mm"
         */
        FORMAT25("yyyy/MM/dd HH:mm"),
        /**
         * "yyyy/MM/dd HH:mm:ss"
         */
        FORMAT26("yyyy/MM/dd HH:mm:ss"),
        /**
         * "yyyy-MM-dd"
         */
        FORMAT27("yyyy-MM-dd"),
        /**
         * "yyyy-MM-dd hh:mm a"
         */
        FORMAT28("yyyy-MM-dd hh:mm a"),
        /**
         * "yyyy-MM-dd hh:mm:ss a"
         */
        FORMAT29("yyyy-MM-dd hh:mm:ss a"),
        /**
         * "yyyy-MM-dd HH:mm"
         */
        FORMAT30("yyyy-MM-dd HH:mm"),
        /**
         * "yyyy-MM-dd HH:mm:ss"
         */
        FORMAT31("yyyy-MM-dd HH:mm:ss");

        private String format;

        private Format(String format) {
            this.format = format;
        }

        @Override
        public String toString() {
            return format;
        }

    }
</code>```

Body:
I'm populating a 'ListView' with an 'ArrayList' using an Adapter.
The 'ArrayList' contains objects with date and time.
When i send the data as it is to the ListView, there is no problem, and the list shows the relevant objects as desired :

public View getView(int position, View convertView, ViewGroup parent) {

  TimePeriod freeSlot = (TimePeriod)getItem(position);

  if (convertView == null) {
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.item, parent, false);
    }

    TextView start = (TextView) convertView.findViewById(R.id.start);
    TextView end = (TextView) convertView.findViewById(R.id.end);

    startTime = freeSlot.getStart().toString()
    endTime = freeSlot.getEnd().toString();
    start.setText(startTime);
    end.setText(endTime);

    return convertView;
}

2017-07-05T10:30:00.000Z 2017-07-05T11:30:00.000Z

But when i use SimpleDateFormat to change the output as i want, it somehow sets the dates of all objects to the same one (01/01) :

startTime = freeSlot.getStart().toString();
endTime = freeSlot.getEnd().toString();

try {
            SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss.SSS'Z'");
            Date newDate = formatter.parse(startTime);
            Date newDate2 = formatter.parse(endTime);

            SimpleDateFormat format = new SimpleDateFormat("dd/MM hh:mm");
            startTime = format.format(newDate);
            SimpleDateFormat format1 = new SimpleDateFormat("hh:mm");
            endTime = format1.format(newDate2);

        } catch (ParseException pe) {
            pe.printStackTrace();
        }

        start.setText(startTime);
        end.setText(endTime);

for start - 01/01 10:30, for end - 11:30

As iv'e mentioned earlier, all objects get this date even though dates & hours are different.

Any ideas? What am i doing wrong?
Thanks a lot!

Body:
use something like this to make it easy,
Create a util class with Below Methods:

 /**
     * Parses @date to String in provided @format
     *
     * @param date   Date
     * @param format Convert to Format
     * @return formatted date string
     */
    public static String DateToString(Date date, String format) {
        if (date != null) {
            try {
                DateFormat dateFormat = new SimpleDateFormat(format);
                return dateFormat.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        } else {
            return "";
        }
    }

    /**
     * Parses date to String in provided format
     *
     * @param date   Date
     * @param format Convert to Format
     * @return formatted date string
     */
    public static String DateToString(Date date, Format format) {
        if (date != null) {
            try {
                DateFormat dateFormat = new SimpleDateFormat(format.format);
                return dateFormat.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        } else {
            return "";
        }
    }

Create static enum/String Format for Reusability. such as below :

 public static enum Format {

        /**
         * "EEE, MMM dd, yyyy, hh:mm a"
         */
        FORMAT1("EEE, MMM dd, yyyy, hh:mm a"),
        /**
         * "dd/MM/yyyy"
         */
        FORMAT2("dd/MM/yyyy"),
        /**
         * "dd/MM/yyyy hh:mm a"
         */
        FORMAT3("dd/MM/yyyy hh:mm a"),
        /**
         * "dd/MM/yyyy hh:mm:ss a"
         */
        FORMAT4("dd/MM/yyyy hh:mm:ss a"),
        /**
         * "dd/MM/yyyy HH:mm"
         */
        FORMAT5("dd/MM/yyyy HH:mm"),
        /**
         * "dd/MM/yyyy HH:mm:ss"
         */
        FORMAT6("dd/MM/yyyy HH:mm:ss"),
        /**
         * "dd-MM-yyyy"
         */
        FORMAT7("dd-MM-yyyy"),
        /**
         * "dd-MM-yyyy hh:mm a"
         */
        FORMAT8("dd-MM-yyyy hh:mm a"),
        /**
         * "dd-MM-yyyy hh:mm:ss a"
         */
        FORMAT9("dd-MM-yyyy hh:mm:ss a"),
        /**
         * "dd-MM-yyyy HH:mm"
         */
        FORMAT10("dd-MM-yyyy HH:mm"),
        /**
         * "dd-MM-yyyy HH:mm:ss"
         */
        FORMAT11("dd-MM-yyyy HH:mm:ss"),
        /**
         * "MM/dd/yyyy"
         */
        FORMAT12("MM/dd/yyyy"),
        /**
         * "MM/dd/yyyy hh:mm a"
         */
        FORMAT13("MM/dd/yyyy hh:mm a"),
        /**
         * "MM/dd/yyyy hh:mm:ss a"
         */
        FORMAT14("MM/dd/yyyy hh:mm:ss a"),
        /**
         * "MM/dd/yyyy HH:mm"
         */
        FORMAT15("MM/dd/yyyy HH:mm"),
        /**
         * "MM/dd/yyyy HH:mm:ss"
         */
        FORMAT16("MM/dd/yyyy HH:mm:ss"),
        /**
         * "MM-dd-yyyy"
         */
        FORMAT17("MM-dd-yyyy"),
        /**
         * "MM-dd-yyyy hh:mm a"
         */
        FORMAT18("MM-dd-yyyy hh:mm a"),
        /**
         * "MM-dd-yyyy hh:mm:ss a"
         */
        FORMAT19("MM-dd-yyyy hh:mm:ss a"),
        /**
         * "MM-dd-yyyy HH:mm"
         */
        FORMAT20("MM-dd-yyyy HH:mm"),
        /**
         * "MM-dd-yyyy HH:mm:ss"
         */
        FORMAT21("MM-dd-yyyy HH:mm:ss"),
        /**
         * "yyyy/MM/dd"
         */
        FORMAT22("yyyy/MM/dd"),
        /**
         * "yyyy/MM/dd hh:mm a"
         */
        FORMAT23("yyyy/MM/dd hh:mm a"),
        /**
         * "yyyy/MM/dd hh:mm:ss a"
         */
        FORMAT24("yyyy/MM/dd hh:mm:ss a"),
        /**
         * "yyyy/MM/dd HH:mm"
         */
        FORMAT25("yyyy/MM/dd HH:mm"),
        /**
         * "yyyy/MM/dd HH:mm:ss"
         */
        FORMAT26("yyyy/MM/dd HH:mm:ss"),
        /**
         * "yyyy-MM-dd"
         */
        FORMAT27("yyyy-MM-dd"),
        /**
         * "yyyy-MM-dd hh:mm a"
         */
        FORMAT28("yyyy-MM-dd hh:mm a"),
        /**
         * "yyyy-MM-dd hh:mm:ss a"
         */
        FORMAT29("yyyy-MM-dd hh:mm:ss a"),
        /**
         * "yyyy-MM-dd HH:mm"
         */
        FORMAT30("yyyy-MM-dd HH:mm"),
        /**
         * "yyyy-MM-dd HH:mm:ss"
         */
        FORMAT31("yyyy-MM-dd HH:mm:ss");

        private String format;

        private Format(String format) {
            this.format = format;
        }

        @Override
        public String toString() {
            return format;
        }

    }


来源: stackexchange

答:
Try this

```<code>for(var regionName in regions) {
    (function (region) {

        region.attr(style);
        region.node.name = regionName; // set node name as regionName

        region[0].addEventListener("mouseover", function() {
            region.animate(hoverStyle, animationSpeed);
        }, true);

        region[0].addEventListener("mouseout", function() {
            region.animate(style, animationSpeed);
        }, true);

        region[0].addEventListener("click", function(d){
            alert(region.node.name); //alert on click
        });
    })(regions[regionName]);
}
</code>```

Jsfiddle demo
https://jsfiddle.net/Lkr4y5bs/

ContentLicense: CC BY-SA 3.0

Title: How to make popup map name using Raphael v2.2.7?

Body:
I'm followed the tutorial of

https://www.jonathan-petitcolas.com/2013/07/18/create-clickable-svg-france-regions-map.html

The maps working fine, now I do not know how to make alert on each map area. For example if the user click area "corse" then the alert shown "corse".

Can anyone help me?

Thanks!

 var MAP_WIDTH  = 620;
    var MAP_HEIGHT = 600;

    var mapContainer = document.getElementById("map");
    var map = new Raphael(mapContainer, MAP_WIDTH, MAP_HEIGHT);

    var style = {
        fill: "#ddd",
        stroke: "#aaa",
        "stroke-width": 1,
        "stroke-linejoin": "round",
        cursor: "pointer"
    };

    var regions = {};
    regions["alsace"] = map.path("M 480.71875,112.28125 477,113.3125 l -1.71875,3 0,2.9375 -1.5625,1.375 -1.375,0 -2.53125,-1.78125 -1.96875,1.375 -2.34375,0 -1.9375,-1.9375 -3.71875,-0.59375 -2.15625,-0.96875 -0.78125,-2.9375 -1.75,1.9375 -0.96875,4.5 -2.5625,0.78125 0,2.53125 2.5625,1.1875 1.9375,1.375 -0.78125,1.75 1.78125,1.15625 3.125,-2.34375 5.4375,3.125 -2.3125,4.3125 0.1875,1.375 1.5625,1.5625 -1.1875,4.09375 -3.90625,3.90625 -2.15625,-0.1875 1.375,1.34375 -0.78125,3.53125 L 459.25,155 l 3.71875,0.96875 -2.15625,4.875 -2.34375,4.6875 0.59375,2.9375 -1.9375,4.5 -3.34375,2.90625 -0.1875,7.625 -2.4375,2.09375 0.0937,0.0625 0.78125,1.5625 3.125,0.1875 3.53125,2.75 0.5625,1.34375 -0.1875,2.34375 -0.96875,1.78125 0.375,2.34375 2.75,-0.40625 0.59375,2.15625 0.96875,4.15625 2.3125,-0.375 -0.40625,2.125 1.375,1.1875 7.21875,-0.1875 3.71875,-2.9375 0.1875,-4.3125 1.96875,-2.53125 -2.5625,-2.9375 -1.34375,-3.125 1.5625,-2.125 0,-4.90625 0.96875,-2.34375 0,-3.90625 1.75,-2.53125 -1.9375,-2.71875 -0.21875,-6.25 5.09375,-9.96875 -0.59375,-5.65625 2.34375,-7.625 0.59375,-6.65625 5.0625,-3.6875 0,-2.34375 1.96875,-2.5625 1.5625,0 1.75,-1.75 -0.375,-3.3125 1.75,-4.6875 2.71875,-0.59375 L 496.5312,115 l -4.875,-0.5625 -4.3125,-2.15625 -2.9375,1.75 -1.5625,-1.75 -2.125,0 z");
    regions["nord-pas-de-calais"] = map.path("m 285.78125,4.0625 -6.25,2.9375 -9.75,1.5625 -11.34375,2.15625 -8.59375,6.625 0,26.375 -0.0625,0.78125 3.03125,0.71875 0.96875,2.15625 2.34375,-0.59375 1.375,-1.75 1.75,0.59375 3.71875,2.90625 1.375,-0.5625 0.96875,2.34375 3.5,1.5625 0,1.9375 2.5625,0.96875 2.53125,-0.96875 4.875,-0.59375 1.1875,1 2.34375,-1 1.15625,1.96875 -2.90625,1.9375 0,2.75 0.96875,0.96875 0.78125,-0.1875 0.5625,-1.5625 1.78125,-1.1875 1.75,1.375 4.09375,1.375 1.75,0 0,-1.96875 2.5625,1.78125 0.1875,1.5625 -1.1875,1.75 2.15625,-1.1875 1.78125,-0.78125 0.75,1.375 0,1.375 2.9375,-1.5625 4.6875,0 1.75,1.75 1.5625,0.40625 1.5625,-1 2.15625,0 0.59375,1.1875 0.78125,-0.1875 2.34375,-1.375 2.34375,1.375 3.125,-2.15625 1.375,0 1.5625,1.375 3.125,-2.15625 1.34375,0.1875 1.1875,0.96875 4.3125,0.40625 0.375,1.75 2.15625,-1.9375 1.15625,0 0.78125,2.53125 3.71875,0.96875 1.0625,-0.71875 -0.3125,0 -0.1875,-1.9375 3.90625,-2.34375 -0.59375,-3.71875 -3.71875,-0.96875 0.96875,-1 0,-2.71875 2.9375,-2.15625 -0.78125,-1.5625 -6.25,-4.875 -10.9375,0.59375 -1.15625,1.9375 -1.375,0 0.1875,-6.84375 -3.125,-3.6875 -2.34375,0.375 -1.375,-1.5625 -3.90625,1.75 -1.34375,-1.34375 -2.75,-0.40625 -0.78125,-2.53125 -0.1875,-7.8125 -1.75,-0.78125 -0.21875,-1.1875 -1.15625,0 -0.40625,-2.34375 -2.53125,0.21875 -4.875,1.5625 -2.34375,2.90625 -2.34375,0 -1.5625,-1.9375 -0.59375,-2.15625 -1.9375,-2.15625 -2.75,0 -1.15625,-2.125 0,-3.34375 1.34375,-2.125 -0.78125,-2.9375 -2.53125,-5.09375 z");
    regions["corse"] = map.path("m 568.92104,452.72493 -2.92969,1.95313 0.39062,1.95312 1.5625,1.95313 -1.75781,1.36719 0.78125,1.5625 -1.17187,1.36718 0,1.75782 1.95312,1.75781 0,2.73437 -1.17187,2.53907 -1.36719,0.58593 -1.5625,-2.14843 -2.73438,0.19531 -0.58593,-0.39063 -2.34375,0 -2.14844,1.95313 -0.78125,3.32031 -5.07813,0.97656 -3.90625,3.32032 -0.78125,2.14843 -1.95312,-0.19531 -0.97656,-1.17187 -0.58594,3.32031 -1.36719,0.58594 -0.39062,3.125 0.58593,1.36718 -2.14843,1.5625 -0.58594,1.5625 -1.5625,0 0,2.14844 1.95312,1.36719 3.32032,1.95312 0.19531,1.56251 -1.95313,0.58593 -3.125,0.58594 0,1.36719 1.17188,1.17187 0.19531,3.90625 4.29688,1.36719 1.5625,0.39063 1.36718,2.14843 -0.97656,1.36719 -1.5625,0.58594 -1.17187,2.14844 -1.17188,1.36718 0.58594,3.51563 2.92969,-0.19531 0.78125,0.58593 2.73437,-1.36718 0.78125,0.78125 -1.36719,2.92968 1.36719,1.36719 -2.34375,1.75781 -1.5625,3.51563 4.29688,0.97656 6.05468,0.58594 -2.53906,2.92969 c 0,0 -1.95312,-0.78125 -1.95312,0.19531 0,0.97656 -1.36719,3.32031 -1.36719,3.32031 l 1.95312,2.14844 3.51563,2.14844 6.64062,1.75781 1.95313,0.78125 1.75781,0.78125 -1.17187,2.14844 3.125,-0.19532 0.58593,1.36719 3.125,0 0.78125,-3.71094 -1.95312,-0.39062 2.73437,-2.92969 -0.97656,-0.97656 0.19531,-1.75781 3.51563,-1.95313 0.19531,-2.14844 -2.34375,-0.19531 -1.5625,1.36719 0,-1.95313 3.125,-0.19531 0.97656,-2.34375 0.78125,-6.83594 -0.58593,-2.92968 -0.19532,-8.59375 4.6875,-6.64063 0,-10.9375 -1.95312,-3.71094 -0.58594,-11.71875 -1.36719,-2.14844 -2.53906,-1.95312 -0.39062,-7.22656 1.17187,-3.32032 -1.5625,-5.27343 -0.97656,-4.29688 -0.78125,-1.17187 -1.75781,-0.97657 z");
    regions["rhone-alpes"] = map.path("m 383.28125,262.59375 -2.15625,0.21875 -1.375,2.53125 -3.6875,14.4375 -1.1875,2.75 -1.375,-0.1875 -0.75,-3.90625 -1,-3.125 -2.125,0.1875 -1.78125,1.75 -1.15625,-1.5625 -1.75,1.5625 -2.375,-1.5625 -1.9375,0 -0.78125,0.59375 -1.15625,6.25 -2.15625,0 -1.5625,1.5625 -1.1875,-1.1875 -6.25,-0.96875 -2.34375,1.375 -1.5625,0 -0.375,-1.375 -2.9375,-0.59375 -0.1875,-3.125 -0.59375,-0.1875 L 336,278.625 l -0.5625,2.15625 1.375,2.71875 0.375,11.125 -4.6875,0.21875 -0.1875,1.75 3.125,2.53125 -1.75,1.75 -0.59375,4.3125 2.34375,3.125 2.125,5.0625 5.09375,3.34375 1.75,6.4375 -3.71875,3.5 0.59375,2.34375 5.46875,1.78125 4.3125,-3.53125 2.125,-0.1875 6.25,2.71875 -0.375,3.71875 3.125,-0.1875 2.53125,2.9375 -1.15625,4.6875 -2.75,1.15625 -1.15625,1.96875 0.78125,2.53125 0.5625,1.375 -2.90625,0 -0.21875,3.6875 -3.125,0.21875 -1.5625,4.875 -4.6875,0 -5.0625,3.71875 -2.8125,4.46875 0.46875,0.59375 1.375,7.1875 3.3125,3.59375 -0.5625,4.125 4.15625,2.5 0,5.53125 2.21875,-1.125 4.6875,3.0625 2.21875,0.8125 0.53125,-3.875 2.78125,-0.53125 0.8125,3.03125 2.78125,-0.28125 0.53125,-3.03125 6.34375,3.5625 1.03125,-2.09375 5.28125,-0.78125 1.15625,1.375 -0.5625,3.90625 0.78125,0.96875 2.90625,-2.9375 2.5625,-0.1875 0.5625,-1.5625 -3.3125,-0.40625 -0.5625,-3.5 2.125,-3.3125 2.75,-0.21875 2.71875,2.5625 -2.71875,3.6875 0.78125,1.375 3.90625,0.40625 2.53125,-2.15625 -1.375,2.9375 0.40625,2.34375 4.09375,0.375 5.46875,0.40625 0.78125,2.53125 2.9375,2.15625 2.53125,0.1875 1.75,-1.5625 1,-2.9375 1.5625,1.375 1.15625,1.375 0.78125,-7.25 -1.9375,-0.375 -1.1875,-2.53125 -6.625,-1.78125 -0.8125,-3.3125 2.375,-1.5625 -1.96875,-1.375 0.40625,-1.75 3.125,0.1875 2.71875,1.375 2.15625,-2.53125 -2.15625,-1.75 0.1875,-2.34375 1.1875,-3.71875 4.09375,-0.40625 3.3125,-1.34375 0.59375,-1.375 -1.5625,-0.78125 0,-2.34375 4.875,0 1.5625,-1.5625 -0.96875,-1.75 2.53125,-1.96875 1.78125,0.78125 2.53125,-2.15625 4.46875,0.78125 1.5625,-1.75 3.71875,0.1875 0,-4.28125 -1.5625,-0.78125 -0.78125,-2.53125 L 434.84375,346 434.25,345.03125 l 0.78125,-4.09375 1.375,-1.1875 3.53125,-0.375 1.15625,1.15625 0.59375,2.75 3.5,-0.40625 0.40625,-2.9375 1.75,-0.78125 3.75,0.1875 -0.0625,-0.125 5.84375,-2.34375 2.15625,1.375 2.15625,0 0.1875,-2.34375 2.53125,-1.375 0.96875,-1.15625 5.09375,-1.96875 0.59375,-3.3125 -1,-1.5625 2.75,-4.6875 L 469.78125,320.875 469,318.125 463.71875,315 c 0,0 0.31502,-5.98725 -0.1875,-7.0625 -0.0158,-0.0269 -0.0497,-0.0773 -0.0625,-0.0937 -0.005,-0.005 -0.0261,-0.0266 -0.0313,-0.0313 -0.004,2.2e-4 -0.0284,-7e-5 -0.0313,0 -5e-5,-0.007 -1.7e-4,-0.0294 0,-0.0313 -0.004,1.2e-4 -0.0284,-4e-5 -0.0313,0 -0.003,-1.5e-4 -0.0283,-7e-5 -0.0313,0 -0.004,-8e-5 -0.0284,10e-6 -0.0313,0 -0.78125,0.19532 -3.6875,0.40625 -3.6875,0.40625 l -2.9375,-3.34375 0.1875,-6.625 6.65625,-2.75 0.78125,-1.9375 -0.40625,-4.3125 -4.28125,-4.46875 -1.375,0.78125 0,-1.78125 0,-2.90625 -3.71875,-1.78125 -0.1875,-1.5625 2.15625,-2.34375 0,-2.71875 -3.53125,-3.71875 -0.1875,-2.53125 -6.65625,0 -4.46875,0.78125 -4.3125,3.5 -1.15625,-1.75 -2.15625,0.1875 -1.96875,4.3125 0.21875,1.75 2.125,1.75 -3.90625,2.5625 -2.53125,2.34375 -6.4375,0 0,-3.71875 2.34375,-1.375 3.5,-0.375 0.21875,-1.96875 -1.1875,-0.78125 2.9375,-3.71875 -0.40625,-1.15625 -3.34375,-1.78125 -8.125,8.9375 -5.65625,0 0,-2.34375 -3.125,-1.5625 -3.71875,4.09375 -2.9375,0.40625 0,-2.75 -2.53125,-1.15625 -3.90625,-5.46875 -3.53125,-1.375 -1.15625,-2.53125 -1.96875,-0.40625 -1.9375,1.375 -1.5625,0.40625 -2.15625,-1.78125 z");
    regions["centre"] = map.path("m 247.15625,126.09375 -1.1875,0.96875 0,3.125 -3.90625,1.9375 0,2.9375 -1.15625,1.375 -4.90625,0 -2.3125,-0.96875 -7.0625,3.6875 -2.71875,0 -2.8125,2.6875 0.65625,0.4375 0.1875,3.34375 4.125,3.5 0.375,7.21875 -1.9375,2.34375 -2.9375,0.59375 -2.9375,1.75 0.40625,1.5625 1.34375,1.78125 0,4.625 0.40625,0.0625 L 223.5,171 l -2.3125,2.9375 -1.5625,2.71875 1.9375,1.78125 -0.1875,4.09375 -0.78125,2.71875 -1.96875,0 0,3.71875 -2.71875,3.53125 -2.9375,1.15625 -1.375,1.75 0.96875,2.34375 -5.65625,1.5625 -1.34375,1.96875 -2.375,-1.5625 1.1875,3.90625 -2.15625,0 -3.90625,-2.75 -1.9375,3.90625 0.96875,1.1875 0,1.15625 -1.96875,2.5625 0.21875,4.28125 -3.125,3.71875 -2.21875,8 0.25,0 0.78125,3.125 3.71875,0.78125 0,2.34375 4.6875,1.375 0,3.71875 -0.1875,2.34375 5.84375,0 5.09375,-1.1875 -0.40625,-2.15625 1.5625,-0.96875 1.5625,2.15625 1.375,0.59375 1.15625,4.6875 3.34375,3.5 0.375,2.75 3.53125,3.5 0,3.71875 -0.78125,2.34375 3.71875,2.9375 1.9375,1.9375 3.125,0.40625 1.1875,4.09375 2.125,1.15625 -0.375,2.9375 -1.5625,0.28125 0.5625,0.125 4.90625,0.375 1.75,-1.75 3.125,3.125 3.90625,-4.5 1.75,1.1875 2.34375,-0.21875 0.78125,0.40625 3.53125,0.1875 1.15625,-3.125 9.78125,1.1875 3.71875,0.96875 6.28125,-0.75 0.9375,-2 2.53125,-2.90625 4.875,-1 2.5625,0.78125 2.71875,-2.125 -0.1875,-1.5625 -0.96875,-0.78125 0,-3.125 5.25,-5.28125 1.96875,2.15625 1.75,-1.78125 1.5625,-0.1875 2.71875,-3.5 4.5,0.375 0.0625,1.0625 1.5,-4.78125 -0.96875,-1.75 0.1875,-2.53125 0.59375,-5.09375 -2.15625,-2.125 0.40625,-4.6875 -1.96875,-4.125 -0.1875,-2.71875 -3.53125,-2.75 L 299.5,216.5 l 1.75,-2.53125 0,-3.71875 -2.34375,-2.71875 -0.1875,-1.96875 3.90625,-1.15625 -0.59375,-2.15625 -0.59375,-3.125 -2.53125,-3.5 -0.59375,-2.15625 3.90625,0 2.75,-1.96875 0.375,-2.90625 -1.75,-1.96875 5.09375,-4.28125 0,-3.53125 -2.5625,-2.71875 -0.96875,-3.125 -3.53125,-3.34375 -4.875,2.75 -0.375,-1.5625 -2.15625,-0.1875 -0.59375,1.5625 -1.9375,0.375 -5.28125,-0.1875 -2.15625,1.375 -1.75,-1.5625 3.125,-2.15625 -0.1875,-3.3125 -2.34375,-1.1875 -1.96875,-2.9375 -5.25,-0.375 -2.15625,-1.75 -2.53125,2.34375 -6.25,0.5625 -0.40625,-5.25 L 264.125,157.53125 263.75,155 l -4.09375,-0.78125 -1.78125,-2.15625 -0.5625,-4.3125 -2.34375,-0.375 -0.40625,-2.15625 -2.71875,-1.9375 -1.375,-3.34375 1.375,-2.34375 -1.375,-1.5625 0,-1.9375 0.78125,-2.15625 -1.5625,-1.5625 -0.59375,-2.34375 -1.9375,-1.9375 z");
    regions["bourgogne"] = map.path("m 318.4375,157.34375 -1.75,1.34375 -7.625,-0.375 -3.5,1.75 -1.375,2.9375 1.5625,1.75 -2.34375,2.75 -1.78125,2.125 3.53125,3.34375 0.96875,3.125 2.5625,2.71875 0,3.53125 -5.09375,4.28125 1.75,1.96875 -0.375,2.90625 -2.75,1.96875 -3.90625,0 0.59375,2.15625 2.53125,3.5 0.59375,3.125 0.59375,2.15625 -3.90625,1.15625 0.1875,1.96875 2.34375,2.71875 0,3.71875 -1.75,2.53125 0.5625,2.34375 3.53125,2.75 0.1875,2.71875 1.96875,4.125 -0.40625,4.6875 2.15625,2.125 -0.59375,5.09375 -0.1875,2.53125 0.96875,1.75 -1.5,4.78125 0.125,1.46875 3.34375,1.5625 L 312,255 l 2.125,-1.1875 1.96875,-1.15625 0.40625,1.75 2.90625,0 0.78125,-1.5625 1.75,0.78125 0.59375,2.53125 1.5625,-0.375 3.71875,-5.09375 1.9375,1.375 3.9375,7.40625 0,2.9375 0.96875,1.1875 3.3125,0 1.15625,1.5625 3.125,0 1.375,1.9375 -0.1875,7.625 -4.09375,3.125 -0.0937,0.21875 0.28125,-0.0313 0.59375,0.1875 0.1875,3.125 2.9375,0.59375 0.375,1.375 1.5625,0 2.34375,-1.375 6.25,0.96875 1.1875,1.1875 1.5625,-1.5625 2.15625,0 1.15625,-6.25 0.78125,-0.59375 1.9375,0 2.375,1.5625 1.75,-1.5625 1.15625,1.5625 1.78125,-1.75 2.125,-0.1875 1,3.125 0.75,3.90625 1.375,0.1875 1.1875,-2.75 3.6875,-14.4375 1.375,-2.53125 2.15625,-0.21875 2.15625,1.78125 1.5625,-0.40625 1.9375,-1.375 1.96875,0.40625 1.15625,2.53125 1.125,0.4375 5.125,-0.625 1.96875,-1.5625 -0.78125,-1.1875 -2.34375,-0.78125 -0.21875,-2.71875 1.96875,-1.375 0.78125,-3.3125 -1.75,-3.125 -1.1875,-1.5625 0.59375,-0.59375 0,-1.9375 -1.5625,-1 -0.40625,-1.5625 4.5,-0.5625 0.40625,-1.5625 -1.375,0 -1.15625,-1.375 -2.15625,0 -1.78125,-2.9375 L 392.25,238 l 0.21875,-2.53125 1.34375,-0.78125 -0.1875,-1 -0.375,-1.15625 0.96875,-1.5625 3.3125,-1.5625 0,-1.5625 1.1875,-1.5625 1.15625,-1.5625 -0.375,-1.375 0.5625,-2.15625 0.40625,-3.125 0.78125,0 -0.1875,-1.15625 -0.78125,-0.78125 -0.21875,-3.90625 -1.75,-0.1875 -0.375,-3.125 -2.15625,-1 0.78125,-0.96875 1.1875,-0.375 2.53125,-2.9375 -0.21875,-1.5625 -1.5625,-3.125 -2.3125,-0.40625 -0.8125,1.96875 -4.28125,0.96875 -0.40625,-0.96875 -3.125,-3.90625 -1.75,0.96875 -2.34375,-0.1875 -0.78125,-1.5625 -3.125,0.1875 -0.1875,-3.3125 -1.75,-1.1875 2.53125,-2.71875 -4.5,-6.0625 -3.5,-3.71875 -3.125,-1.75 -5.65625,0 -0.40625,2.53125 -2.53125,1.375 -6.4375,0.1875 -1,2.15625 -1.375,-0.1875 -1.15625,-2.15625 -3.90625,1.96875 -7.8125,-0.40625 -0.96875,-2.15625 -2.15625,-2.90625 -0.375,-3.53125 -3.125,-3.71875 -1.96875,1.375 -3.53125,-2.71875 0.59375,-5.28125 -5.0625,-5.28125 -2.34375,0 -1.375,-1.15625 z");
    regions["poitou-charentes"] = map.path("m 188.75,225.6875 -3.71875,3.90625 -1.34375,2.34375 -1.375,-1.15625 -0.59375,-1.375 -5.28125,0.1875 -4.875,0.96875 -5.28125,0.40625 0,2.71875 -2.71875,1.78125 -6.0625,-1.375 -4.09375,1.75 1.9375,2.75 0,2.34375 4.6875,3.90625 -1.15625,2.53125 3.125,3.5 -1.375,1.78125 1.9375,2.90625 0.59375,5.46875 -1.15625,1.5625 1.375,2.34375 -1.375,2.5625 0.1875,1.5625 1.5625,-1.1875 1.9375,1.96875 -2.71875,1.75 L 162,272.75 l -2.15625,0.59375 -2.53125,1.1875 -3.125,-2.34375 -3.71875,1.5625 -1.15625,-3.125 -2.75,0.1875 -5.96875,3.625 1.4375,1.3125 -3.125,2.53125 -0.375,1.96875 -2.9375,0.375 -1.5625,-1.75 -3.90625,-0.375 -0.40625,-1.96875 -2.34375,-1.5625 -3.3125,1.1875 2.15625,3.125 2.71875,0 2.75,1.75 2.15625,1.75 4.09375,-0.1875 0.78125,1.75 2.71875,0.59375 1,2.71875 1.75,0.78125 -0.1875,2.15625 -2.34375,-0.375 -0.78125,1.15625 1.75,2.53125 -0.96875,4.3125 -2.34375,-0.1875 0.1875,2.71875 0.59375,0.96875 -2.75,0 -0.375,-1.5625 1.75,-2.34375 -0.59375,-1.34375 -0.96875,-0.78125 L 136.75,291 l -3.3125,-0.40625 -2.71875,-3.3125 -0.40625,6.84375 4.5,3.3125 0.375,3.71875 0.78125,4.28125 0.40625,4.3125 2.34375,-0.21875 4.09375,3.34375 2.75,1.5625 0.1875,1.9375 2.15625,0.40625 6.25,6.25 1.46875,6.75 5.78125,0 0.96875,-0.96875 0.1875,2.9375 5.09375,0.59375 0.78125,6.25 2.75,0.1875 4.46875,4.5 2.34375,0.375 2.75,-1.375 1.9375,1.375 1.5625,-3.3125 2.15625,-3.71875 3.90625,0.40625 1.9375,-1.78125 3.53125,-3.5 0.1875,-6.84375 9.1875,-6.25 0.1875,-4.6875 2.75,-0.375 1.75,-3.125 1.09375,0.0313 0.65625,-2.96875 1.5625,-0.1875 0.96875,-2.75 1.96875,-0.59375 2.34375,-1.5625 -0.375,-4.875 1.75,-0.59375 3.5,-0.78125 -0.1875,-1.75 -0.59375,-2.71875 -2.71875,-0.21875 -1.5625,-1.75 0.96875,-1.75 0.1875,-5.28125 -1.34375,-1.5625 1.5625,-1.15625 2.53125,-2.9375 4.28125,-0.1875 0,-2.34375 2.15625,-1.78125 5.28125,-0.96875 0.375,-2.9375 -2.125,-1.15625 -1.1875,-4.09375 -3.125,-0.40625 -1.9375,-1.9375 -3.71875,-2.9375 0.78125,-2.34375 0,-3.71875 -3.53125,-3.5 -0.375,-2.75 -3.34375,-3.5 -1.15625,-4.6875 -1.375,-0.59375 -1.5625,-2.15625 -1.5625,0.96875 0.40625,2.15625 -5.09375,1.1875 -5.84375,0 0.1875,-2.34375 0,-3.71875 -4.6875,-1.375 0,-2.34375 -3.71875,-0.78125 -0.78125,-3.125 -1.75,0 z");
    regions["limousin"] = map.path("m 256.125,267.875 -1.15625,3.125 -3.53125,-0.1875 -0.78125,-0.40625 -2.34375,0.21875 -1.75,-1.1875 -3.90625,4.5 -3.125,-3.125 -1.75,1.75 -4.90625,-0.375 -0.5625,-0.125 -3.71875,0.6875 -2.15625,1.78125 0,2.34375 -4.28125,0.1875 -2.53125,2.9375 -1.5625,1.15625 1.34375,1.5625 -0.1875,5.28125 -0.96875,1.75 1.5625,1.75 2.71875,0.21875 0.59375,2.71875 0.1875,1.75 -3.5,0.78125 -1.75,0.59375 0.375,4.875 -2.34375,1.5625 -1.96875,0.59375 -0.96875,2.75 -1.5625,0.1875 -0.65625,2.96875 4.5625,0.15625 1,1.9375 -0.8125,2.15625 1.78125,2.34375 1.34375,-0.375 1.375,-1.96875 6.25,0.59375 1,3.90625 4.28125,0.59375 0.96875,1.34375 -2.9375,1.375 1.375,0.96875 4.125,0.59375 1.15625,2.9375 2.15625,1.75 -3.90625,3.53125 0,2.71875 1.5625,0.78125 -1.5625,1.96875 2.15625,1.75 -1.5625,1.9375 1.75,1.1875 4.28125,-0.1875 -0.1875,4.28125 1.625,2.5625 0.59375,-0.0937 4.15625,-1.9375 4.96875,2.21875 3.84375,5.5 2.21875,-0.28125 3.3125,-3.3125 1.09375,1.9375 2.21875,-2.1875 3.03125,0.8125 0.0937,0.65625 2.53125,-1.78125 -0.78125,-1.9375 -1.1875,-1.1875 1.5625,-1.9375 1.5625,0 1,-3.125 0.78125,-1.5625 -0.59375,-3.53125 2.53125,-3.5 3.53125,-2.15625 0.1875,-5.46875 1.75,0.96875 1.96875,2.15625 1.9375,0 1.1875,-1.375 -0.96875,-2.34375 0.96875,-3.5 -0.59375,-3.3125 -1.1875,-1.375 0,-2.75 1.78125,-2.90625 -0.40625,-2.75 -4.5,-4.5 -0.375,-1.75 3.71875,-2.15625 2.15625,-1.15625 0.5625,-2.75 2.34375,-1.75 L 288.9375,291.5 287.375,289.5625 287,283.5 l -2.15625,-5.0625 -2.15625,-0.78125 -1.5625,-2.75 -1.375,1.75 -1.34375,-1.75 0,-2.34375 -2.34375,-3.3125 -6.4375,0.78125 -3.71875,-0.96875 -9.78125,-1.1875 z");
    regions["aquitaine"] = map.path("m 209.84375,310.46875 -1.75,3.125 -2.75,0.375 -0.1875,4.6875 -9.1875,6.25 -0.1875,6.84375 -3.53125,3.5 -1.9375,1.78125 -3.90625,-0.40625 -2.15625,3.71875 -1.5625,3.3125 -1.9375,-1.375 -2.75,1.375 -2.34375,-0.375 -4.46875,-4.5 -2.75,-0.1875 -0.78125,-6.25 -5.09375,-0.59375 -0.1875,-2.9375 -0.96875,0.96875 -5.78125,0 0.28125,1.25 1.375,5.65625 0.375,5.65625 -0.96875,1.5625 -0.96875,-4.6875 -2.75,-10.71875 -9.96875,-9 0.21875,-4.09375 -1.96875,-0.1875 -3.125,4.6875 -0.96875,16.40625 -2.53125,16.59375 -1.78125,12.875 -0.1875,3.34375 1.375,-4.5 2.71875,-3.53125 3.90625,3.53125 0.40625,1.15625 1.15625,1.5625 -4.875,0.21875 -0.78125,-1.1875 -1.9375,0.78125 -0.40625,2.9375 -2.15625,2.9375 0,4.46875 -3.5,18.75 -4.5,17.1875 -1.375,6.65625 -1.15625,4.6875 -3.71875,6.4375 -4.5,5.46875 -3.5,1.375 -2.53125,0.375 0,2.15625 2.34375,2.15625 3.5,0.1875 0.1875,2.53125 2.75,0.21875 0.78125,-1.78125 3.71875,1.5625 2.34375,0.59375 0.5625,2.34375 -1.34375,1.1875 0,3.6875 -2.75,1.375 -0.1875,1.75 1.75,1.96875 3.125,0.96875 0.59375,-2.9375 1.75,-1.9375 -0.1875,2.53125 1.375,1.96875 3.5,0 1.5625,2.125 4.6875,0.78125 4.5,2.75 7.40625,0 0.40625,4.09375 5.0625,3.90625 1.96875,2.34375 2.15625,-1.15625 1.9375,-0.40625 0.96875,0.96875 1.78125,-0.96875 3.40625,-1.875 0.3125,-4.03125 1.5625,-1.1875 0.8125,-6.4375 2.90625,0.59375 1.1875,-0.78125 -1.375,-2.75 5.28125,-4.5 3.125,-7.03125 1.9375,-2.53125 -2.34375,-3.5 -1.5625,-2.34375 2.15625,-1.96875 -3.3125,-5.46875 -5.28125,-0.375 -1.5625,-2.75 1.375,-3.71875 1.9375,-2.53125 -0.59375,-3.3125 1.5625,-1.5625 -2.3125,-3.90625 1.9375,-2.34375 2.15625,-0.40625 1.9375,0.78125 2.75,-2.34375 0.96875,2.9375 0.96875,1.375 2.15625,-0.59375 -0.1875,-2.53125 1.375,-2.9375 2.3125,1.96875 3.125,-3.125 1.375,1.9375 3.3125,-0.59375 3.53125,-0.375 1.5625,-2.75 5.84375,-0.5625 2.9375,2.90625 1,-0.96875 1.9375,-0.59375 -0.78125,-2.71875 2.9375,-0.78125 3.71875,-0.78125 -0.8125,-2.34375 1.1875,-1.375 0.96875,-3.71875 -2.15625,-2.34375 1.375,-4.46875 2.9375,1.75 4.3125,-0.78125 -1.96875,-4.3125 -1.5625,-5.84375 3.90625,-0.1875 0.96875,-2.5625 1.78125,-1.75 0.1875,-2.9375 4.28125,-0.375 2.75,-3.90625 -1.1875,-0.40625 -0.1875,-2.125 3.3125,-0.40625 0.21875,-1.9375 1.5625,-1 1.75,-3.125 -1.75,-1.9375 0,-2.15625 1.34375,-1.15625 -1.75,-2.75 0.1875,-4.28125 -4.28125,0.1875 -1.75,-1.1875 1.5625,-1.9375 -2.15625,-1.75 1.5625,-1.96875 -1.5625,-0.78125 0,-2.71875 3.90625,-3.53125 -2.15625,-1.75 -1.15625,-2.9375 -4.125,-0.59375 -1.375,-0.96875 2.9375,-1.375 -0.96875,-1.34375 -4.28125,-0.59375 -1,-3.90625 -6.25,-0.59375 -1.375,1.96875 -1.34375,0.375 -1.78125,-2.34375 0.8125,-2.15625 -1,-1.9375 -5.65625,-0.1875 z");
    regions["midi-pyrenees"] = map.path("m 247.46875,347.3125 -4.15625,1.9375 -0.59375,0.0937 0.125,0.1875 -1.34375,1.15625 0,2.15625 1.75,1.9375 -1.75,3.125 -1.5625,1 -0.21875,1.9375 -3.3125,0.40625 0.1875,2.125 1.1875,0.40625 -2.75,3.90625 -4.28125,0.375 -0.1875,2.9375 -1.78125,1.75 -0.96875,2.5625 -3.90625,0.1875 1.5625,5.84375 1.96875,4.3125 -4.3125,0.78125 -2.9375,-1.75 -1.375,4.46875 2.15625,2.34375 -0.96875,3.71875 -1.1875,1.375 0.8125,2.34375 -3.71875,0.78125 -2.9375,0.78125 0.78125,2.71875 -1.9375,0.59375 -1,0.96875 -2.9375,-2.90625 -5.84375,0.5625 -1.5625,2.75 -3.53125,0.375 -3.3125,0.59375 -1.375,-1.9375 -3.125,3.125 -2.3125,-1.96875 -1.375,2.9375 0.1875,2.53125 -2.15625,0.59375 -0.96875,-1.375 -0.96875,-2.9375 -2.75,2.34375 -1.9375,-0.78125 -2.15625,0.40625 -1.9375,2.34375 2.3125,3.90625 -1.5625,1.5625 0.59375,3.3125 -1.9375,2.53125 -1.375,3.71875 1.5625,2.75 5.28125,0.375 3.3125,5.46875 -2.15625,1.96875 1.5625,2.34375 2.34375,3.5 -1.9375,2.53125 -3.125,7.03125 -5.28125,4.5 1.375,2.75 -1.1875,0.78125 -2.90625,-0.59375 -0.8125,6.4375 -1.5625,1.1875 -0.3125,4.03125 0.5,-0.28125 3.3125,1.96875 3.90625,2.9375 0.375,2.34375 3.125,2.53125 2.5625,0 6.4375,-2.75 2.71875,3.125 3.71875,1 1.375,-2.34375 1.75,0.78125 11.71875,0.78125 0.40625,-9.59375 2.71875,0.40625 5.09375,2.9375 6.03125,1.15625 2.5625,0 3.3125,4.3125 8.40625,-0.40625 3.3125,5.28125 2.9375,-1.1875 8.59375,1.1875 0.625,3.59375 6.0625,-1.40625 2.21875,-1.9375 3.3125,-0.84375 0.8125,-1.65625 7.1875,-0.53125 -4.40625,-5.25 -3.59375,1.9375 -6.34375,-5.25 1.375,-1.9375 4.96875,0 -0.5625,-4.6875 0,-3.59375 -0.8125,-6.65625 -9.6875,-4.6875 0.5625,-1.65625 -2.21875,-2.46875 2.5,-1.125 0.53125,-3.03125 3.0625,-1.375 -0.84375,-1.9375 2.78125,-2.5 1.375,2.5 4.125,-1.375 1.9375,-0.28125 -0.28125,1.375 3.875,0 3.59375,1.125 0.28125,-3.59375 1.65625,0 6.0625,1.09375 5.8125,0 4.40625,-1.375 1.125,-3.59375 -3.03125,-2.78125 0.8125,-2.75 1.65625,-2.46875 2.75,1.90625 7.1875,-2.46875 1.125,-2.21875 1.65625,0 3.3125,0 -0.28125,-5.78125 0,-1.9375 1.65625,0 3.03125,1.65625 3.03125,0 -0.53125,-3.3125 1.65625,-1.40625 3.3125,-0.53125 0,-2.78125 3.59375,-1.65625 -0.84375,-3.84375 -3.03125,0 -2.75,-0.5625 -0.5625,-2.21875 2.21875,-0.53125 0,-2.78125 2.1875,-1.9375 -1.65625,-0.8125 -4.6875,0.8125 0.28125,-2.1875 -3.3125,-1.40625 -0.84375,-6.625 0,-4.6875 -2.75,-1.9375 0.28125,-3.875 -5.8125,-7.15625 -0.5625,-5.53125 -1.90625,0 -0.84375,-5.53125 -3.875,0.5625 -0.53125,-3.59375 -0.5625,-0.84375 -5.53125,4.71875 0,4.6875 -1.375,0 -0.5625,4.40625 -1.375,0.5625 -1.09375,2.46875 -6.09375,0 -0.53125,-0.8125 -2.78125,0 -1.65625,2.75 -2.1875,-0.28125 1.09375,-3.3125 -2.5,-1.09375 2.5,-5.8125 -3.3125,-2.46875 -1.125,-7.1875 -3.03125,-0.8125 -2.21875,2.1875 -1.09375,-1.9375 -3.3125,3.3125 -2.21875,0.28125 -3.84375,-5.5 -4.96875,-2.21875 z");
    regions["languedoc-roussillon"] = map.path("m 320.78125,352.25 -5.46875,1.96875 -1.5625,3.5 -3.5,-2.34375 -2.75,8.59375 -2.8125,6.46875 4.09375,5.03125 -0.28125,3.875 2.75,1.9375 0,4.6875 0.84375,6.625 3.3125,1.40625 -0.28125,2.1875 4.6875,-0.8125 1.65625,0.8125 -2.1875,1.9375 0,2.78125 -2.21875,0.53125 0.5625,2.21875 2.75,0.5625 3.03125,0 0.84375,3.84375 -3.59375,1.65625 0,2.78125 -3.3125,0.53125 -1.65625,1.40625 0.53125,3.3125 -3.03125,0 -3.03125,-1.65625 -1.65625,0 0,1.9375 0.28125,5.78125 -3.3125,0 -1.65625,0 -1.125,2.21875 -7.1875,2.46875 -2.75,-1.90625 -1.65625,2.46875 -0.8125,2.75 3.03125,2.78125 -1.125,3.59375 -4.40625,1.375 -5.8125,0 -6.0625,-1.09375 -1.65625,0 -0.28125,3.59375 -3.59375,-1.125 -3.875,0 0.28125,-1.375 -1.9375,0.28125 -4.125,1.375 -1.375,-2.5 -2.78125,2.5 0.84375,1.9375 -3.0625,1.375 -0.53125,3.03125 -2.5,1.125 2.21875,2.46875 -0.5625,1.65625 9.6875,4.6875 0.8125,6.65625 0,3.59375 0.5625,4.6875 -4.96875,0 -1.375,1.9375 6.34375,5.25 3.59375,-1.9375 4.40625,5.25 -7.1875,0.53125 -0.8125,1.65625 -3.3125,0.84375 -2.21875,1.9375 -6.0625,1.40625 0.34375,2.0625 2.9375,2.75 5.84375,1.5625 0.1875,3.5 3.125,2.75 2.34375,-0.40625 3.34375,-4.09375 4.09375,-0.78125 6.4375,2.15625 5.46875,4.6875 1.5625,-1.96875 1.375,0 1.375,0.96875 1.15625,-0.5625 0.1875,-2.75 5.875,-1.375 1.9375,-2.53125 2.9375,-0.96875 4.09375,0 2.5625,2.71875 3.125,0.21875 0,-3.125 -1.5625,-2.15625 -2.75,-1.1875 -0.59375,-22.65625 0.21875,-6.4375 -2.34375,0.1875 -1.96875,-2.90625 1.5625,-2.5625 3.3125,3.125 2.9375,-2.34375 1.96875,-1.9375 0.375,-3.125 7.03125,-2.15625 0.78125,-1.75 5.46875,-0.1875 1.75,-2.15625 10.5625,-8.40625 6.625,-4.6875 5.6875,0.40625 0,3.90625 4.46875,-0.21875 2.40625,0.125 1.75,-4.0625 6.34375,-3.875 -1.375,-1.9375 1.65625,-4.40625 5.78125,0.8125 1.40625,-10.5 7.71875,-4.40625 0,-2.5 -5.8125,-5.78125 0,-4.4375 -3.3125,-5.5 -6.90625,-3.875 -0.53125,3.03125 -2.78125,0.28125 -0.8125,-3.03125 -2.78125,0.53125 -0.53125,3.875 -2.21875,-0.8125 -4.6875,-3.0625 -2.21875,1.125 0,-5.53125 -4.15625,-2.5 0.5625,-4.125 -3.3125,-3.59375 -1.375,-7.1875 -4.96875,-6.34375 -3.625,0.875 -0.78125,-2.71875 -1.96875,0 -0.375,2.34375 -5.0625,1.5625 -3.53125,-9 z");
    regions["provence-alpes-cote-dazur"] = map.path("m 447.34375,339.15625 -1.75,0.78125 -0.40625,2.9375 -3.5,0.40625 -0.59375,-2.75 -1.15625,-1.15625 -3.53125,0.375 -1.375,1.1875 -0.78125,4.09375 0.59375,0.96875 4.09375,0.40625 0.78125,2.53125 1.5625,0.78125 0,4.28125 -3.71875,-0.1875 -1.5625,1.75 -4.46875,-0.78125 -2.53125,2.15625 -1.78125,-0.78125 -2.53125,1.96875 0.96875,1.75 -1.5625,1.5625 -4.875,0 0,2.34375 1.5625,0.78125 -0.59375,1.375 -3.3125,1.34375 -4.09375,0.40625 -1.1875,3.71875 -0.1875,2.34375 2.15625,1.75 -2.15625,2.53125 -2.71875,-1.375 -3.125,-0.1875 -0.40625,1.75 1.96875,1.375 -2.375,1.5625 0.8125,3.3125 6.625,1.78125 1.1875,2.53125 1.9375,0.375 -0.78125,7.25 -1.15625,-1.375 -1.5625,-1.375 -1,2.9375 -1.75,1.5625 -2.53125,-0.1875 -2.9375,-2.15625 -0.78125,-2.53125 -5.46875,-0.40625 -4.09375,-0.375 -0.40625,-2.34375 1.375,-2.9375 -2.53125,2.15625 -3.90625,-0.40625 -0.78125,-1.375 2.71875,-3.6875 -2.71875,-2.5625 -2.75,0.21875 -2.125,3.3125 0.5625,3.5 3.3125,0.40625 -0.5625,1.5625 -2.5625,0.1875 -2.90625,2.9375 -0.78125,-0.96875 0.5625,-3.90625 -1.15625,-1.375 -5.28125,0.78125 -1.03125,2.09375 0.5625,0.3125 3.3125,5.5 0,4.4375 5.8125,5.78125 0,2.5 -7.71875,4.40625 -1.40625,10.5 -5.78125,-0.8125 -1.65625,4.40625 1.375,1.9375 -6.34375,3.875 -1.75,4.0625 6.1875,0.28125 8.21875,0.59375 1.5625,1.5625 -2.9375,0 -1.9375,3.3125 8.375,1.75 6.65625,-1.15625 -3.53125,-3.34375 2.34375,-1.9375 3.71875,1.5625 1.75,3.71875 11.15625,0.1875 2.90625,-1.1875 0.59375,1.78125 -3.125,2.71875 4.3125,0.1875 -0.78125,1.96875 -1.1875,1.375 9.5625,0 4.6875,1.5625 1,1.34375 3.5,1.5625 0.96875,3.90625 2.15625,0.40625 1.96875,-1.375 3.5,-2.15625 6.0625,0.59375 -0.1875,1.5625 -1.96875,0.96875 4.6875,0.21875 -1.15625,-1.1875 -0.40625,-2.53125 2.53125,-1.75 2.9375,0.96875 1.1875,0.375 0.96875,1.1875 1.375,-0.96875 0.375,-2.5625 1.5625,-1.34375 4.09375,0 1.1875,-1.78125 2.71875,0.78125 3.125,-1.34375 0,-5.09375 -4.09375,0.1875 3.125,-1.9375 1.5625,-2.15625 0.40625,-3.125 5.65625,-0.78125 3.3125,-3.71875 0.1875,-4.46875 3.90625,0.78125 1.375,-1.78125 1.96875,0.40625 0.1875,-6.0625 4.5,-0.375 3.90625,-3.53125 3.5,0 0.1875,-2.15625 3.53125,-2.125 -1.96875,-4.5 2.9375,-2.53125 -0.59375,-2.9375 4.3125,-1.375 1.15625,-4.28125 -0.5625,-2.9375 -1,-1.75 L 496.125,390 l -2.90625,0.21875 -9.1875,3.3125 -2.9375,0 -5.0625,-4.09375 -5.09375,-1.375 -2.9375,0 0,-3.53125 -4.09375,-2.53125 0,-3.90625 2.75,-0.375 -1.5625,-1.375 -1.96875,-0.59375 -0.96875,-2.53125 0.78125,-1.75 3.5,-3.71875 -0.5625,-2.75 2.34375,-2.53125 2.125,0.1875 0,-1.75 -2.71875,-1.375 -0.59375,-5.65625 -2.15625,-0.78125 -2.71875,0.40625 -5.09375,-2.5625 -0.78125,-5.84375 -2.90625,-0.96875 -1,-1.96875 -1.28125,-2.8125 -3.75,-0.1875 z");

    for(var regionName in regions) {
        regions[regionName].attr(style);
    }

    var animationSpeed = 500;
    var hoverStyle = {
        fill: "#A8BED5"
    }

    var i = 0;
    var arr_data = {};
    for(var regionName in regions) {
        arr_data[i] = regionName;
        (function (region) {

            region.attr(style);

            region[0].addEventListener("mouseover", function() {
                region.animate(hoverStyle, animationSpeed);
            }, true);

            region[0].addEventListener("mouseout", function() {
                region.animate(style, animationSpeed);
            }, true);

            region[0].addEventListener("click", function(d){
//                console.log(regions);
                alert(JSON.stringify(arr_data));
            });
            i++;

        })(regions[regionName]);
    }

Body:
Try this

for(var regionName in regions) {
    (function (region) {

        region.attr(style);
        region.node.name = regionName; // set node name as regionName

        region[0].addEventListener("mouseover", function() {
            region.animate(hoverStyle, animationSpeed);
        }, true);

        region[0].addEventListener("mouseout", function() {
            region.animate(style, animationSpeed);
        }, true);

        region[0].addEventListener("click", function(d){
            alert(region.node.name); //alert on click
        });
    })(regions[regionName]);
}

Jsfiddle demo
https://jsfiddle.net/Lkr4y5bs/


问:
fatal: read error: Connection reset by peer
Can some one help me to get rid of following:

```<code>vijay13@ubuntu:~$ git clone git://anongit.kde.org/plasma-mediacenter

Cloning into 'plasma-mediacenter'...

fatal: read error: Connection reset by peer
</code>```

And

```<code>vijay13@ubuntu:~$ git clone git@git.kde.org:plasma-mediacenter

Cloning into 'plasma-mediacenter'...

Read from socket failed: Connection reset by peer

fatal: The remote end hung up unexpectedly
</code>```

How to get rid of both above issues?

答:
I also have faced with this problem.

The problem is solved when i replace "git://" with "https://"

```<code>root@ubuntu:~# git clone git://github.com/osrg/ryu.git
Cloning into 'ryu'...
fatal: read error: Connection reset by peer

root@ubuntu:~# git clone https://github.com/osrg/ryu.git
Cloning into 'ryu'...
remote: Counting objects: 25613, done.
remote: Compressing objects: 100% (5/5), done.
Receiving objects:  37% (9609/25613), 18.68 MiB | 60.00 KiB/s
</code>```

Body:
Can some one help me to get rid of following:

vijay13@ubuntu:~$ git clone git://anongit.kde.org/plasma-mediacenter

Cloning into 'plasma-mediacenter'...

fatal: read error: Connection reset by peer

And

vijay13@ubuntu:~$ git clone git@git.kde.org:plasma-mediacenter

Cloning into 'plasma-mediacenter'...

Read from socket failed: Connection reset by peer

fatal: The remote end hung up unexpectedly

How to get rid of both above issues?

Body:
I also have faced with this problem.

The problem is solved when i replace "git://" with "https://"

root@ubuntu:~# git clone git://github.com/osrg/ryu.git
Cloning into 'ryu'...
fatal: read error: Connection reset by peer

root@ubuntu:~# git clone https://github.com/osrg/ryu.git
Cloning into 'ryu'...
remote: Counting objects: 25613, done.
remote: Compressing objects: 100% (5/5), done.
Receiving objects:  37% (9609/25613), 18.68 MiB | 60.00 KiB/s


问:
WPF: Change Colors of Elements in User Control if "IsEnabled=False"
I have a UserControl which consists of a grid with 3 columns:

```<code>Name="Test">

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            ...
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

<Grid Width="{StaticResource DoubleOverallWidthUserControls}" Height="{StaticResource DoubleHeightControls}">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{StaticResource GridLengthUserControlLabel}" />
        <ColumnDefinition Width="{StaticResource GridLengthUserControlContent}" />
        <ColumnDefinition Width="{StaticResource GridLengthUserControlUnits}" />
    </Grid.ColumnDefinitions>

    <Border
        Grid.Row="0"
        Grid.Column="0"
        BorderBrush="{StaticResource BrushTextInputBorder}"
        BorderThickness="0,0,0,1"
        Cursor="Arrow">
        <TextBlock
            x:Name="TextBlockLabel"
            Width="{StaticResource DoubleWidthUserControlLabel}"
            VerticalAlignment="Center"
            DockPanel.Dock="Top"
            TextAlignment="Left" />
    </Border>
    <Border BorderBrush="{StaticResource BrushBorder}" CornerRadius="3,3,0,0" Grid.Row="0"
        Grid.Column="1" Background="White">
    <TextBox
        x:Name="TextBoxText"
        Width="{StaticResource DoubleWidthUserControlContent}" />
        <Border.Style>
            <Style TargetType="Border">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=Test, Path=IsEnabled}" Value="False">
                        <Setter Property="Background" Value="Gray"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
    </Border>

    <TextBlock
        x:Name="TextBlockUnit"
        Grid.Row="0"
        Grid.Column="2"
        Width="{StaticResource DoubleWidthUserControlUnits}"
        Margin="10,0,0,0"
        VerticalAlignment="Center" />
</Grid>
</code>```

Now I want to change the following things in my control if it is disabled:

column 1: grid bottom border color

column 2: background color of the white border element in which the transparent textbox is wrapped

can someone help me?

答:
A Style Setter only works when you have not set the property directly. This is because the direct assignment creates a so-called local value, which has higher precedence than the value from a Style Setter. See Dependency Property Value Precedence for details.

Since you want to disable two borders, you may create the following Style in Resource:

```<code><UserControl.Resources>
    <Style x:Key="BorderStyle" TargetType="Border">
        <Setter Property="Background" Value="White"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=Test, Path=IsEnabled}"
                         Value="False">
                 <Setter Property="Background" Value="Gray"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
</code>```

Assign this style to your border.

```<code><Border Style="{StaticResource BorderStyle}"/>
</code>```

You could even make this a default Style in the UserControl by omitting the x:Key

```<code><UserControl.Resources>
    <Style TargetType="Border">
        ...
    </Style>
</UserControl.Resources>
</code>```

so that you would not have to explicitly set the Style property if the Buttons:

```<code><Border>
    ...
</Border>
</code>```

Body:
I have a UserControl which consists of a grid with 3 columns:

Name="Test">

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            ...
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

<Grid Width="{StaticResource DoubleOverallWidthUserControls}" Height="{StaticResource DoubleHeightControls}">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{StaticResource GridLengthUserControlLabel}" />
        <ColumnDefinition Width="{StaticResource GridLengthUserControlContent}" />
        <ColumnDefinition Width="{StaticResource GridLengthUserControlUnits}" />
    </Grid.ColumnDefinitions>

    <Border
        Grid.Row="0"
        Grid.Column="0"
        BorderBrush="{StaticResource BrushTextInputBorder}"
        BorderThickness="0,0,0,1"
        Cursor="Arrow">
        <TextBlock
            x:Name="TextBlockLabel"
            Width="{StaticResource DoubleWidthUserControlLabel}"
            VerticalAlignment="Center"
            DockPanel.Dock="Top"
            TextAlignment="Left" />
    </Border>
    <Border BorderBrush="{StaticResource BrushBorder}" CornerRadius="3,3,0,0" Grid.Row="0"
        Grid.Column="1" Background="White">
    <TextBox
        x:Name="TextBoxText"
        Width="{StaticResource DoubleWidthUserControlContent}" />
        <Border.Style>

            </Style>
        </Border.Style>
    </Border>

    <TextBlock
        x:Name="TextBlockUnit"
        Grid.Row="0"
        Grid.Column="2"
        Width="{StaticResource DoubleWidthUserControlUnits}"
        Margin="10,0,0,0"
        VerticalAlignment="Center" />
</Grid>

Now I want to change the following things in my control if it is disabled:

column 1: grid bottom border color

column 2: background color of the white border element in which the transparent textbox is wrapped

can someone help me?

Body:
A Style Setter only works when you have not set the property directly. This is because the direct assignment creates a so-called local value, which has higher precedence than the value from a Style Setter. See Dependency Property Value Precedence for details.

Since you want to disable two borders, you may create the following Style in Resource:

<UserControl.Resources>
    <Style x:Key="BorderStyle" TargetType="Border">
        <Setter Property="Background" Value="White"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=Test, Path=IsEnabled}"
                         Value="False">
                 <Setter Property="Background" Value="Gray"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

Assign this style to your border.

<Border Style="{StaticResource BorderStyle}"/>

You could even make this a default Style in the UserControl by omitting the x:Key

<UserControl.Resources>
    <Style TargetType="Border">
        ...
    </Style>
</UserControl.Resources>

so that you would not have to explicitly set the Style property if the Buttons:

<Border>
    ...
</Border>


问:
Swift method documentation - not showing in autocomplete
I am documenting my Swift methods as follows:

```<code>/// Extracts the server time from the API call response.
/// - parameter response: The HTTPURLResponse from which to extract the date.
/// - returns: The 'Date' header from the response, as a `Date` object.
/// - throws: If the 'Date' header is not found, or cannot be parsed to a `Date` object.
static func extractServerTimeFromResponse(_ response: HTTPURLResponse) throws -> Date {
    guard let serverTimeString = response.allHeaderFields["Date"] as? String else {
        throw RGOTimeSyncHelperError.invalidServerResponse
    }
    let formatter = DateFormatter()
    formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
    guard let serverTime = formatter.date(from: serverTimeString) else {
        throw RGOTimeSyncHelperError.dateParsingError
    }
    return serverTime
}

/// Calculates the offset of the local time compared to the server time.
/// - parameter serverTime: The time from the server.
/// - returns: The amount of seconds that need to be added to the client time, to match the server time.
static func calculateOffset(serverTime: Date) -> Int {
    let localTime = Date()
    let offset = Calendar.current.dateComponents([.second], from: localTime, to: serverTime).second!
    return offset
}

/// Add an offset in seconds to a given date.
/// - parameter date: The date to which to offset should be applied.
/// - parameter bySeconds: The offset, in seconds, that will be applied to the given date.
/// - returns: A new `Date` object, comprised of the given date, with the given offset applied.
static func offset(date: Date, bySeconds offset: Int) -> Date {
    let offsetDate = Calendar.current.date(byAdding: .second, value: offset, to: date)!
    return offsetDate

}
</code>```

When I alt-click on the method signature anywhere, Xcode shows the quickhelp panel with the information that I have entered shown correctly.

However, when I start typing the method signature and autocomplete pops up, it does not show this information at the bottom of the autocomplete box as it does for Apple's APIs.

Where in my comment syntax am I going wrong?

答:
The reason is that Xcode parse the documentation displayed in the popover from a separate doc-set and not from the class files themselves.

Have a look here: https://stackoverflow.com/a/43982094/1415898
for a more complete answer.

Body:
I am documenting my Swift methods as follows:

/// Extracts the server time from the API call response.
/// - parameter response: The HTTPURLResponse from which to extract the date.
/// - returns: The 'Date' header from the response, as a `Date` object.
/// - throws: If the 'Date' header is not found, or cannot be parsed to a `Date` object.
static func extractServerTimeFromResponse(_ response: HTTPURLResponse) throws -> Date {
    guard let serverTimeString = response.allHeaderFields["Date"] as? String else {
        throw RGOTimeSyncHelperError.invalidServerResponse
    }
    let formatter = DateFormatter()
    formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
    guard let serverTime = formatter.date(from: serverTimeString) else {
        throw RGOTimeSyncHelperError.dateParsingError
    }
    return serverTime
}

/// Calculates the offset of the local time compared to the server time.
/// - parameter serverTime: The time from the server.
/// - returns: The amount of seconds that need to be added to the client time, to match the server time.
static func calculateOffset(serverTime: Date) -> Int {
    let localTime = Date()
    let offset = Calendar.current.dateComponents([.second], from: localTime, to: serverTime).second!
    return offset
}

/// Add an offset in seconds to a given date.
/// - parameter date: The date to which to offset should be applied.
/// - parameter bySeconds: The offset, in seconds, that will be applied to the given date.
/// - returns: A new `Date` object, comprised of the given date, with the given offset applied.
static func offset(date: Date, bySeconds offset: Int) -> Date {
    let offsetDate = Calendar.current.date(byAdding: .second, value: offset, to: date)!
    return offsetDate

}

When I alt-click on the method signature anywhere, Xcode shows the quickhelp panel with the information that I have entered shown correctly.

However, when I start typing the method signature and autocomplete pops up, it does not show this information at the bottom of the autocomplete box as it does for Apple's APIs.

Where in my comment syntax am I going wrong?


问:
Where to place constant attributes?
I want to write clean code in java and I am very insecure where to place my attriutes.

I often cannot decide, if I place them on top of the class, in a constructor or directly in the method. Are there some rules out there? The only logic one for me is, to place attributes on top of the class when these attributes are used in more than one method.

Can you evaluate this code in terms of clean code? Should I place the constant currency attributes in the constructor? Can I also put some of the class attributes in a method? Thanks for the advice

```<code>public class CsvFileReader  {
    private SimpleDateFormatStringToDate formatter = new SimpleDateFormatStringToDate();
    private IataExchangeRateDataSet exchangeRateDataSet= new IataExchangeRateDataSet();
    private final String SEMICOLON_DELIMITER = ";";

    // Currency attributes index
    private final int CURRENCY_VALUE = 1;
    private final int CURRENCY_ISO_CODE = 2;
    private final int CURRENCY_PERIOD_START = 3;
    private final int CURRENCY_PERIOD_END = 4;

    public CsvFileReader(IataExchangeRateDataSet exchangeRateDataSet) {
        this.exchangeRateDataSet = exchangeRateDataSet;
    }

    public void readCsvFile(String fileName, final int maxLengthOfColumn) {

        BufferedReader fileReader = null;
        try {
            String line = "";
            fileReader = new BufferedReader(new FileReader(fileName));

            while ((line = fileReader.readLine()) != null) {

                String[] tokens = line.split(SEMICOLON_DELIMITER);

                //TODO: Noch auf Vollständigkeit der Zeile, Korrektheit der Datumsformate und ähnliches überprüfen
                if ( tokens.length== maxLengthOfColumn && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_START]) && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_END])) {

                    //format currency value in csv
                    tokens[CURRENCY_VALUE]=tokens[CURRENCY_VALUE].replace(",", ".");

                    IataExchangeRateData iataExchangeRateData = new IataExchangeRateData(
                            new BigDecimal(tokens[CURRENCY_VALUE]), tokens[CURRENCY_ISO_CODE],
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_START]),
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_END]));

                    exchangeRateDataSet.getExchangeRateDataSet().add(iataExchangeRateData);
                }
            }
        }

        catch (Exception e) {
            System.out.println("Error in CsvFileReader");
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                System.out.println("Error while closing fileReader !!!");
                e.printStackTrace();
            }
        }
    }
}
</code>```

答:
clean code questions usually spark off arguments, some right and others not so right. But I have felt the way you do now about constants and I have used them just the way you did in your code i.e. right above the constructor. But more recently, I put them in an interface. Something a little like this

```<code>public interface CurrencyConstants {
    int CURRENCY_VALUE = 1;
    int CURRENCY_ISO_CODE = 2;
    int CURRENCY_PERIOD_START = 3;
    int CURRENCY_PERIOD_END = 4;
}
</code>```

Then I simply import the interface and use the constants like so..

```<code>CurrencyConstants.CURRENCY_VALUE
</code>```

This helps if the constants are used in more than one class. Cheers!

Title: Where to place constant attributes?

Body:
I want to write clean code in java and I am very insecure where to place my attriutes.

I often cannot decide, if I place them on top of the class, in a constructor or directly in the method. Are there some rules out there? The only logic one for me is, to place attributes on top of the class when these attributes are used in more than one method.

Can you evaluate this code in terms of clean code? Should I place the constant currency attributes in the constructor? Can I also put some of the class attributes in a method? Thanks for the advice

public class CsvFileReader  {
    private SimpleDateFormatStringToDate formatter = new SimpleDateFormatStringToDate();
    private IataExchangeRateDataSet exchangeRateDataSet= new IataExchangeRateDataSet();
    private final String SEMICOLON_DELIMITER = ";";

    // Currency attributes index
    private final int CURRENCY_VALUE = 1;
    private final int CURRENCY_ISO_CODE = 2;
    private final int CURRENCY_PERIOD_START = 3;
    private final int CURRENCY_PERIOD_END = 4;

    public CsvFileReader(IataExchangeRateDataSet exchangeRateDataSet) {
        this.exchangeRateDataSet = exchangeRateDataSet;
    }

    public void readCsvFile(String fileName, final int maxLengthOfColumn) {

        BufferedReader fileReader = null;
        try {
            String line = "";
            fileReader = new BufferedReader(new FileReader(fileName));

            while ((line = fileReader.readLine()) != null) {

                String[] tokens = line.split(SEMICOLON_DELIMITER);

                //TODO: Noch auf Vollständigkeit der Zeile, Korrektheit der Datumsformate und ähnliches überprüfen
                if ( tokens.length== maxLengthOfColumn && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_START]) && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_END])) {

                    //format currency value in csv
                    tokens[CURRENCY_VALUE]=tokens[CURRENCY_VALUE].replace(",", ".");

                    IataExchangeRateData iataExchangeRateData = new IataExchangeRateData(
                            new BigDecimal(tokens[CURRENCY_VALUE]), tokens[CURRENCY_ISO_CODE],
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_START]),
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_END]));

                    exchangeRateDataSet.getExchangeRateDataSet().add(iataExchangeRateData);
                }
            }
        }

        catch (Exception e) {
            System.out.println("Error in CsvFileReader");
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                System.out.println("Error while closing fileReader !!!");
                e.printStackTrace();
            }
        }
    }
}

Body:
clean code questions usually spark off arguments, some right and others not so right. But I have felt the way you do now about constants and I have used them just the way you did in your code i.e. right above the constructor. But more recently, I put them in an interface. Something a little like this

public interface CurrencyConstants {
    int CURRENCY_VALUE = 1;
    int CURRENCY_ISO_CODE = 2;
    int CURRENCY_PERIOD_START = 3;
    int CURRENCY_PERIOD_END = 4;
}

Then I simply import the interface and use the constants like so..

CurrencyConstants.CURRENCY_VALUE

This helps if the constants are used in more than one class. Cheers!


问:
I am trying to check runtime permissions by calling a class inside fragment. But onRequestPermissionsResult is not working inside fragment
I am trying to check runtime permissions inside a fragment by calling permissions class but in fragment overided  method to get result of permissions granted or not is not working in fragment

Here is method of class where i check or request permissions

```<code> public boolean checkPermissionForExternalStorage(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

 public void requestPermissionForExternalStorage(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        }
    }
</code>```

Here is my Fragment

```<code>    package in.prsc.com.prscportal;

import android.Manifest;
import android.app.DownloadManager;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.widget.LinearLayoutCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * Created by Bhuvan on 05-Aug-16.
 */
public class LEP extends Fragment {
    View myView;
    ProgressBar pb;
    WebView mWebView;
    private ValueCallback<Uri> mUploadMessage;
    public ValueCallback<Uri[]> uploadMessage;
    public static final int REQUEST_SELECT_FILE = 100;
    private final static int FILECHOOSER_RESULTCODE = 1;
    public static int temp_perm;
    MarshmallowPermissions marshmallowPermissions;

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (requestCode == REQUEST_SELECT_FILE) {
                if (uploadMessage == null)
                    return;
                uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
                uploadMessage = null;
            }
        } else if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == mUploadMessage)
                return;
            // Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
            // Use RESULT_OK only if you're implementing WebView inside an Activity
            Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        } else
            Toast.makeText(getActivity().getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myView = inflater.inflate(R.layout.web_front, container, false);
        pb = (ProgressBar) myView.findViewById(R.id.progressBar);
        mWebView = (WebView) myView.findViewById(R.id.webview);

        marshmallowPermissions = new MarshmallowPermissions(getActivity());
        if (Build.VERSION.SDK_INT >= 23) {
            if (!marshmallowPermissions.checkPermissionForExternalStorage()) {
                marshmallowPermissions.requestPermissionForExternalStorage();
            }
        }

        return myView;

    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MarshmallowPermissions.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                   // Here i have to do my code after permissions granted

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

}
</code>```

答:
I got the Answer
I tried and check permissions in my fragment instead of calling from other class and it works

Apply below code in oncreate of fragment

```<code>    if (Build.VERSION.SDK_INT >= 23) {
       checkPermissionForExternalStorage();

    }

    return myView;

}

@RequiresApi(api = Build.VERSION_CODES.M)
public boolean checkPermissionForExternalStorage(){
    int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (result == PackageManager.PERMISSION_GRANTED){
        return true;
    } else {
       requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        return true;
    }
}
</code>```

Override below method in fragment

```<code>@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        Log.d("req_result", "success");
        switch (requestCode) {
            case EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Do your stuff here after user granted permissions
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
</code>```

Body:
I am trying to check runtime permissions inside a fragment by calling permissions class but in fragment overided  method to get result of permissions granted or not is not working in fragment

Here is method of class where i check or request permissions

 public boolean checkPermissionForExternalStorage(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

 public void requestPermissionForExternalStorage(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        }
    }

Here is my Fragment

    package in.prsc.com.prscportal;

import android.Manifest;
import android.app.DownloadManager;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.widget.LinearLayoutCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * Created by Bhuvan on 05-Aug-16.
 */
public class LEP extends Fragment {
    View myView;
    ProgressBar pb;
    WebView mWebView;
    private ValueCallback<Uri> mUploadMessage;
    public ValueCallback<Uri[]> uploadMessage;
    public static final int REQUEST_SELECT_FILE = 100;
    private final static int FILECHOOSER_RESULTCODE = 1;
    public static int temp_perm;
    MarshmallowPermissions marshmallowPermissions;

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (requestCode == REQUEST_SELECT_FILE) {
                if (uploadMessage == null)
                    return;
                uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
                uploadMessage = null;
            }
        } else if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == mUploadMessage)
                return;
            // Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
            // Use RESULT_OK only if you're implementing WebView inside an Activity
            Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        } else
            Toast.makeText(getActivity().getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myView = inflater.inflate(R.layout.web_front, container, false);
        pb = (ProgressBar) myView.findViewById(R.id.progressBar);
        mWebView = (WebView) myView.findViewById(R.id.webview);

        marshmallowPermissions = new MarshmallowPermissions(getActivity());
        if (Build.VERSION.SDK_INT >= 23) {
            if (!marshmallowPermissions.checkPermissionForExternalStorage()) {
                marshmallowPermissions.requestPermissionForExternalStorage();
            }
        }

        return myView;

    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MarshmallowPermissions.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                   // Here i have to do my code after permissions granted

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

}

Body:
I got the Answer
I tried and check permissions in my fragment instead of calling from other class and it works

Apply below code in oncreate of fragment

    if (Build.VERSION.SDK_INT >= 23) {
       checkPermissionForExternalStorage();

    }

    return myView;

}

@RequiresApi(api = Build.VERSION_CODES.M)
public boolean checkPermissionForExternalStorage(){
    int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (result == PackageManager.PERMISSION_GRANTED){
        return true;
    } else {
       requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        return true;
    }
}

Override below method in fragment

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        Log.d("req_result", "success");
        switch (requestCode) {
            case EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Do your stuff here after user granted permissions
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }


问:
add click event to Jquery UI accordian Header
When you create a Jquery UI accordian you get a bunch of headers, that when you click them a div opens. However, I would like to preform an additional action upon clicking the header.

How do i do this?

Any ideas?

Thanks!

答:
Javascript

```<code>$("#CreateNewUserHeader").click(function() {
    alert("test");
});
</code>```

html

```<code><h3 id = "CreateNewUserHeader"><a >Create New User</a></h3>
<div>some stuff</div>
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Javascript

$("#CreateNewUserHeader").click(function() {
    alert("test");
});

html

<h3 id = "CreateNewUserHeader"><a >Create New User</a></h3>
<div>some stuff</div>


问:
Check for warnings of deprecation and new methods
Recently I submitted my app on AppStore with a method setting badgecolor of tabbaritem.

```<code>    [[[AppDelegate globalDelegate].tabBarController viewControllers] objectAtIndex:1].tabBarItem.badgeColor = kTabBarBadgeColor;
</code>```

This badgeColor came in iOS 10 only and my app supported iOS 8 and above. I had no idea about it and the app got approved. Now, I have to resubmit my app with fixing this issue.

I want to know if there is a way to find out such cases where methods get deprecated or are visible in specific OS versions only.

答:
By changing target of Xcode project you can see errors & warnings while building.

If you need more info,
You can visible all API changes like Added,Modified & Deprecated variants in Apple documentation

it will give you searching options for both Swift & Objective C

Searching UITabBarItem Instance Property badgeColor. it gives API changes are none.Supporting SDK's version

```<code>SDKs
iOS 10.0+
tvOS 10.0+
</code>```

Searching finishedSelectedImage instance method of UITabBarItem.

```<code>SDK
iOS 5.0–7.0 Deprecated
</code>```

Deprecated Use selectedImage with UIImageRenderingModeAlwaysOriginal
  instead.

Body:
Recently I submitted my app on AppStore with a method setting badgecolor of tabbaritem.

    [[[AppDelegate globalDelegate].tabBarController viewControllers] objectAtIndex:1].tabBarItem.badgeColor = kTabBarBadgeColor;

This badgeColor came in iOS 10 only and my app supported iOS 8 and above. I had no idea about it and the app got approved. Now, I have to resubmit my app with fixing this issue.

I want to know if there is a way to find out such cases where methods get deprecated or are visible in specific OS versions only.

Body:
By changing target of Xcode project you can see errors & warnings while building.

If you need more info,
You can visible all API changes like Added,Modified & Deprecated variants in Apple documentation

it will give you searching options for both Swift & Objective C

Searching UITabBarItem Instance Property badgeColor. it gives API changes are none.Supporting SDK's version

SDKs
iOS 10.0+
tvOS 10.0+

Searching finishedSelectedImage instance method of UITabBarItem.

SDK
iOS 5.0–7.0 Deprecated

Deprecated Use selectedImage with UIImageRenderingModeAlwaysOriginal
  instead.


问:
Exclude certain token pattern from production rule in JavaCC
Assume that we have the production rule Expression that can choose between LogicExpression, MathExpression, StringExpression, and ListExpression.

```<code>void Expression() #void: {}
{
    LOOKAHEAD(3) LogicExpression() | LOOKAHEAD(3) MathExpression() |
    LOOKAHEAD(2) StringExpression() | ListExpression()
}
</code>```

All four of these production rules may evaluate to the token IDENTIFIER, so the expression IDENTIFIER + 1 will encounter a ParseException because the IDENTIFIER resolves to a LogicExpression instead of the whole thing resolving to a MathExpression. Is there a way to exclude a lone IDENTIFIER from being part of a production rule?

答:
No.  There isn't a straightforward way to match everything that matches a pattern X except those that match a pattern Y.

But that's not your problem.  Your problem seems to be that you want to parse expressions.  There is a straight-forward way to do that.

```<code>void Expression() #void: {}
{
    LOOKAHEAD(LogicExpression())
    LogicExpression()
|
    LOOKAHEAD(MathExpression())
    MathExpression()
|
    LOOKAHEAD(StringExpression())
    StringExpression()
|
    ListExpression()
}
</code>```

For inputs that can be matched more by more than one of the choices, the first choice that works will by chosen.

Body:
Assume that we have the production rule Expression that can choose between LogicExpression, MathExpression, StringExpression, and ListExpression.

void Expression() #void: {}
{
    LOOKAHEAD(3) LogicExpression() | LOOKAHEAD(3) MathExpression() |
    LOOKAHEAD(2) StringExpression() | ListExpression()
}

All four of these production rules may evaluate to the token IDENTIFIER, so the expression IDENTIFIER + 1 will encounter a ParseException because the IDENTIFIER resolves to a LogicExpression instead of the whole thing resolving to a MathExpression. Is there a way to exclude a lone IDENTIFIER from being part of a production rule?

Body:
No.  There isn't a straightforward way to match everything that matches a pattern X except those that match a pattern Y.

But that's not your problem.  Your problem seems to be that you want to parse expressions.  There is a straight-forward way to do that.

void Expression() #void: {}
{
    LOOKAHEAD(LogicExpression())
    LogicExpression()
|
    LOOKAHEAD(MathExpression())
    MathExpression()
|
    LOOKAHEAD(StringExpression())
    StringExpression()
|
    ListExpression()
}

For inputs that can be matched more by more than one of the choices, the first choice that works will by chosen.


问:
Cannot find the Nagios binary or no execute permissions in NagiosQL
I downloaded nagiosql_320.tar.gz and installed NagiosQL. When I click on check configuration file, it shows error as:

Cannot find the Nagios binary or no execute permissions!

I created symlink as below for nagios binary with following permission.

```<code>lrwxrwxrwx 1 root root 28 Jul  5 16:07 /usr/sbin/nagios -> /usr/local/nagios/bin/nagios

-rwxr-x--- 1 nagios apache 692624 Jun 27 14:40 /usr/local/nagios/bin/nagios
</code>```

How can I correct the error?

答: chmod +x /usr/local/nagios/bin/nagios and try again

Body:
I downloaded nagiosql_320.tar.gz and installed NagiosQL. When I click on check configuration file, it shows error as:

Cannot find the Nagios binary or no execute permissions!

I created symlink as below for nagios binary with following permission.

lrwxrwxrwx 1 root root 28 Jul  5 16:07 /usr/sbin/nagios -> /usr/local/nagios/bin/nagios

-rwxr-x--- 1 nagios apache 692624 Jun 27 14:40 /usr/local/nagios/bin/nagios

How can I correct the error?


问:
Routing constraints for multiple controllers under top level route
I'm looking for some feedback on both the philosophy of good practice and technical practice of using a top level route that routes to multiple Models based on conditions.

I need to have a top level route domain.com/:id that either routes to a: Company or User.

The condition/identifier being that a User has an @ in the url, e.g. domain.com/@theminijohn

My routes for the moment look like this:

```<code>devise_for :users, path: '',
  path_names: {
    sign_up: '',
    registration: 'signup',
    sign_in: 'login',
    password: 'password',
    confirmation: 'verification'
  },
  controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
    omniauth_callbacks: 'users/omniauth_callbacks',
    passwords: 'users/passwords'
  }

resources :users, path: '', only: [:show] do
  member do
    get 'reviews', to: 'users#reviews', as: :reviews
    get :following, :followers
    post :follow, to: 'users#follow_user'
    post :unfollow, to: 'users#unfollow_user'
  end
end

resources :companies, path: '', only: [:show], as: :company do
  resources :products, path: '', only: [:show], as: :product
end
</code>```

Furthermore the @ sign will only be used in the url, aka it is not present in the attribute.

How do I go about this ?

Edit: Here's where I am:

the constraint that gets called from the route for the :users resource

```<code>module Constraints
  class UserProfile
    def matches?(request)
      if request.path.include?('@')
        slug = request.path.delete('/@')
        User.where(slug: slug).exists?
      end
    end
  end
end
</code>```

and in the controller I patched the find method to:

```<code>def set_user
  @user = User.includes(:reviews).find(params[:id].delete('@'))
end
</code>```

答:
How I ended up solving this:

1) Include the @ in the friendly_id slug

To do this I had to patch the normalize function which strips it out when calling .parameterize

```<code># overwrite normalize function because it's stripping
# out '@' when calling .parameterize
def normalize_friendly_id(value)
  "@" + value.to_s.parameterize
end
</code>```

2) Regenerate all slugs

There are various methods, I went with deleting the slug and generating it again.

```<code>User.each do |u|
  u.update_attribute(:slug, nil)
end

User.find_each(&:save)
</code>```

Have in mind should_generate_new_friendly_id? & if you overwrote it.

3) Routing Constraint

I wrapped my User routes in a constraint:

```<code>constraints(Constraints::UserProfile.new) do
  resources :users,
  ....
end
</code>```

which looks like this:

```<code>module Constraints
  class UserProfile
    def matches?(request)
      if request.path.match? /\/@(.*)/
        slug = request.path.split('/')[1]
        User.where(slug: slug).exists?
      end
    end
  end
end
</code>```

Voilà.

Body:
I'm looking for some feedback on both the philosophy of good practice and technical practice of using a top level route that routes to multiple Models based on conditions.

I need to have a top level route domain.com/:id that either routes to a: Company or User.

The condition/identifier being that a User has an @ in the url, e.g. domain.com/@theminijohn

My routes for the moment look like this:

devise_for :users, path: '',
  path_names: {
    sign_up: '',
    registration: 'signup',
    sign_in: 'login',
    password: 'password',
    confirmation: 'verification'
  },
  controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
    omniauth_callbacks: 'users/omniauth_callbacks',
    passwords: 'users/passwords'
  }

resources :users, path: '', only: [:show] do
  member do
    get 'reviews', to: 'users#reviews', as: :reviews
    get :following, :followers
    post :follow, to: 'users#follow_user'
    post :unfollow, to: 'users#unfollow_user'
  end
end

resources :companies, path: '', only: [:show], as: :company do
  resources :products, path: '', only: [:show], as: :product
end

Furthermore the @ sign will only be used in the url, aka it is not present in the attribute.

How do I go about this ?

Edit: Here's where I am:

the constraint that gets called from the route for the :users resource

module Constraints
  class UserProfile
    def matches?(request)
      if request.path.include?('@')
        slug = request.path.delete('/@')
        User.where(slug: slug).exists?
      end
    end
  end
end

and in the controller I patched the find method to:

def set_user
  @user = User.includes(:reviews).find(params[:id].delete('@'))
end

Body:
How I ended up solving this:

1) Include the @ in the friendly_id slug

To do this I had to patch the normalize function which strips it out when calling .parameterize

# overwrite normalize function because it's stripping
# out '@' when calling .parameterize
def normalize_friendly_id(value)
  "@" + value.to_s.parameterize
end

2) Regenerate all slugs

There are various methods, I went with deleting the slug and generating it again.

User.each do |u|
  u.update_attribute(:slug, nil)
end

User.find_each(&:save)

Have in mind should_generate_new_friendly_id? & if you overwrote it.

3) Routing Constraint

I wrapped my User routes in a constraint:

constraints(Constraints::UserProfile.new) do
  resources :users,
  ....
end

which looks like this:

module Constraints
  class UserProfile
    def matches?(request)
      if request.path.match? /\/@(.*)/
        slug = request.path.split('/')[1]
        User.where(slug: slug).exists?
      end
    end
  end
end

Voilà.


问:
wordpress custom post type loop does not work with pagination
Working with a custom post type, which works perfect. All custom posts are showen, but I cant get the pagination to work correct.

Once I click on the next the page is redirected to /page/2/ which does not exict.

Untill now I could not find a working solution online so why is this not working?

Here's the code that I use:

```<code>$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'paged'          => $paged
) );

// the loop
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();

    the_title();

endwhile;

    next_posts_link( '← '.__( 'next' , 'ff' ) ,  $query->max_num_pages );
    previous_posts_link( '← '.__( 'prev' , 'ff' ) , $query->max_num_pages );

    wp_reset_postdata();

endif;
</code>```

答:
You can write this code for custom post pagination :</p>

```<code><?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ($paged == "1") {
    $query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'offset' => 0
) );
} else {
    $offset = $paged * 5;
    $offset = $offset - 5;
   $query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'offset' => $offset
) );
}

if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
    /*Your Code */

endwhile;
?>
<div class="pagination-grp">
    <?php
    $big = 999999999; // need an unlikely integer
    //$i=1;

    echo paginate_links(array(
        'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
        'format' => '?paged=%#%',
        'current' => max(1, get_query_var('paged')),
        'prev_text' => __('<'),
        'next_text' => __('>'),
        'total' => $query->max_num_pages

    ));
    wp_reset_postdata();
    endif;
    ?>
</div>
</code>```

Body:
Working with a custom post type, which works perfect. All custom posts are showen, but I cant get the pagination to work correct.

Once I click on the next the page is redirected to /page/2/ which does not exict.

Untill now I could not find a working solution online so why is this not working?

Here's the code that I use:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'paged'          => $paged
) );

// the loop
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();

    the_title();

endwhile;

    next_posts_link( '← '.__( 'next' , 'ff' ) ,  $query->max_num_pages );
    previous_posts_link( '← '.__( 'prev' , 'ff' ) , $query->max_num_pages );

    wp_reset_postdata();

endif;

Body:
You can write this code for custom post pagination :

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if ($paged == "1") {
    $query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'offset' => 0
) );
} else {
    $offset = $paged * 5;
    $offset = $offset - 5;
   $query = new WP_Query( array(
    'post_type'      => 'projects',
    'posts_per_page' => 5,
    'offset' => $offset
) );
}

if ($query->have_posts()) :
while ($query->have_posts()) : $query->the_post();
    /*Your Code */

endwhile;
?>
<div class="pagination-grp">
    <?php
    $big = 999999999; // need an unlikely integer
    //$i=1;

    echo paginate_links(array(
        'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
        'format' => '?paged=%#%',
        'current' => max(1, get_query_var('paged')),
        'prev_text' => __('<'),
        'next_text' => __('>'),
        'total' => $query->max_num_pages

    ));
    wp_reset_postdata();
    endif;
    ?>
</div>


问:
Flask click command unittests - how to use testing app with "with_appcontext" decorator?
I don't know how to correctly use testing app version while unittesting (with pytest) flask cli command (with click) decorated with with_app_context decorator. This decorator replaces pytest fixture app with the "normal", development application. I use app factory pattern.

My command in a simplified version looks like this (mind @with_appcontext):

```<code>@click.command()
@click.option('--username', prompt='Username')
@click.option('--email', prompt='User E-Mail')
@click.option('--password', prompt='Password', confirmation_prompt=True, hide_input=True)
@with_appcontext  # from flask.cli import with_appcontext
def createsuperuser(username, email, password):
    user = User(
        username=username,
        email=email,
        password=password,
        active=True,
        is_admin=True,
    )
    user.save()
</code>```

Without @with_appcontext unittests work just fine (they get the app injected by pytest), but the command itself does not, as it needs an app context.

My extracted pytest code:

```<code># pytest fixtures
@pytest.yield_fixture(scope='function')
def app():
    """An application for the tests."""
    _app = create_app(TestConfig)
    ctx = _app.test_request_context()
    ctx.push()

    yield _app

    ctx.pop()

@pytest.yield_fixture(scope='function')
def db(app):
    """A database for the tests."""
    _db.app = app
    with app.app_context():
        _db.create_all()

    yield _db

    # Explicitly close DB connection
    _db.session.close()
    _db.drop_all()

@pytest.mark.usefixtures('db')
class TestCreateSuperUser:
    # db fixture uses app fixture, works the same if app was injected here as well
    def test_user_is_created(self, cli_runner, db):
        result = cli_runner.invoke(
            createsuperuser,
            input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass'
        )
        assert result.exit_code == 0
        assert 'SUCCESS' in result.output
        # etc.
</code>```

All my tests using app and db fixtures work just fine apart from these decorated ones. I'm not sure how I should workaround this with_appcontext decorator that sets the app itself.

Thank you in advance for any hint.

答:
Inspiration taken from https://github.com/pallets/flask/blob/master/tests/test_cli.py#L254.

```<code>from flask.cli import ScriptInfo

    @pytest.fixture
    def script_info(app):
        return ScriptInfo(create_app=lambda info: app)
</code>```

In your test:

```<code>def test_user_is_created(self, cli_runner, db, script_info):
    result = cli_runner.invoke(
        createsuperuser,
        input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass',
        obj=obj,
    )
</code>```

Body:
I don't know how to correctly use testing app version while unittesting (with pytest) flask cli command (with click) decorated with with_app_context decorator. This decorator replaces pytest fixture app with the "normal", development application. I use app factory pattern.

My command in a simplified version looks like this (mind @with_appcontext):

@click.command()
@click.option('--username', prompt='Username')
@click.option('--email', prompt='User E-Mail')
@click.option('--password', prompt='Password', confirmation_prompt=True, hide_input=True)
@with_appcontext  # from flask.cli import with_appcontext
def createsuperuser(username, email, password):
    user = User(
        username=username,
        email=email,
        password=password,
        active=True,
        is_admin=True,
    )
    user.save()

Without @with_appcontext unittests work just fine (they get the app injected by pytest), but the command itself does not, as it needs an app context.

My extracted pytest code:

# pytest fixtures
@pytest.yield_fixture(scope='function')
def app():
    """An application for the tests."""
    _app = create_app(TestConfig)
    ctx = _app.test_request_context()
    ctx.push()

    yield _app

    ctx.pop()

@pytest.yield_fixture(scope='function')
def db(app):
    """A database for the tests."""
    _db.app = app
    with app.app_context():
        _db.create_all()

    yield _db

    # Explicitly close DB connection
    _db.session.close()
    _db.drop_all()

@pytest.mark.usefixtures('db')
class TestCreateSuperUser:
    # db fixture uses app fixture, works the same if app was injected here as well
    def test_user_is_created(self, cli_runner, db):
        result = cli_runner.invoke(
            createsuperuser,
            input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass'
        )
        assert result.exit_code == 0
        assert 'SUCCESS' in result.output
        # etc.

All my tests using app and db fixtures work just fine apart from these decorated ones. I'm not sure how I should workaround this with_appcontext decorator that sets the app itself.

Thank you in advance for any hint.

Body:
Inspiration taken from https://github.com/pallets/flask/blob/master/tests/test_cli.py#L254.

from flask.cli import ScriptInfo

    @pytest.fixture
    def script_info(app):
        return ScriptInfo(create_app=lambda info: app)

In your test:

def test_user_is_created(self, cli_runner, db, script_info):
    result = cli_runner.invoke(
        createsuperuser,
        input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass',
        obj=obj,
    )